Add attachement to control point
Closed this issue · 1 comments
The controler must be in capacity to prove the control and add an attachement.
Voici un guide détaillé, étape par étape, pour créer une classe Attachment
qui peut être utilisée dans plusieurs autres classes, avec des mises en œuvre évolutives afin d'ajouter des améliorations front-end, telles que Dropzone.js, ultérieurement. Ce guide couvrira les impacts sur les vues basées sur les classes, les formulaires, et les améliorations potentielles futures.
Étape 1 : Création de la classe Attachment
Objectif
Nous allons d'abord créer une classe Attachment
qui pourra être liée à plusieurs modèles via une relation ManyToManyField
. Cela permet de lier plusieurs fichiers à plusieurs objets de modèles différents, ce qui offre une grande flexibilité.
Implémentation
- Modèle
Attachment
: Ce modèle gérera les fichiers eux-mêmes, et pourra être lié à plusieurs autres modèles.
from django.db import models
class Attachment(models.Model):
file = models.FileField(upload_to='attachments/')
name = models.CharField(max_length=255, blank=True)
def __str__(self):
return self.name if self.name else self.file.name
Explications :
file
: Le fichier uploadé.name
: Un nom optionnel pour chaque fichier, au cas où tu souhaites afficher un nom plus convivial que le nom du fichier.
Étape 2 : Lier Attachment
aux autres modèles
Objectif
Nous allons lier le modèle Attachment
à d'autres classes via une relation ManyToManyField
. Cela permet à un modèle (par exemple, Project
, Task
, etc.) d'avoir plusieurs fichiers joints, et ces fichiers peuvent également être associés à d'autres objets.
Implémentation
Supposons que tu souhaites ajouter des pièces jointes à un modèle Project
et un modèle Task
. Tu vas simplement ajouter un champ ManyToManyField
à chaque modèle.
class Project(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
attachments = models.ManyToManyField('Attachment', blank=True, related_name='projects')
def __str__(self):
return self.name
class Task(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
attachments = models.ManyToManyField('Attachment', blank=True, related_name='tasks')
def __str__(self):
return self.title
Explications :
attachments
: Le champManyToManyField
qui relie plusieurs fichiers à un objet.related_name
: Cela te permet de récupérer les projets ou tâches associés à un fichier donné. Par exemple,attachment.projects.all()
retourne tous les projets liés à une pièce jointe.
Étape 3 : Création des formulaires
Objectif
Nous allons maintenant créer les formulaires pour permettre aux utilisateurs de télécharger des fichiers et de les associer à des objets, tels que des projets ou des tâches.
Implémentation
- Formulaire pour
Project
:
from django import forms
from .models import Project
class ProjectForm(forms.ModelForm):
attachments = forms.FileField(required=False, widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Project
fields = ['name', 'description']
- Formulaire pour
Task
:
from django import forms
from .models import Task
class TaskForm(forms.ModelForm):
attachments = forms.FileField(required=False, widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta:
model = Task
fields = ['title', 'description']
Explications :
attachments
: Le champFileField
est ajouté manuellement au formulaire pour gérer les fichiers multiples via l'attributmultiple=True
. Cela permet d’uploader plusieurs fichiers simultanément.forms.ClearableFileInput
: Ce widget permet d'afficher une interface d'upload de fichiers avec la possibilité de supprimer les fichiers sélectionnés avant l'envoi.
Étape 4 : Création des vues basées sur des classes
Objectif
Nous allons maintenant configurer les vues basées sur des classes pour gérer la création et la mise à jour de projets et de tâches, tout en prenant en compte les fichiers joints.
Implémentation
- Vue
ProjectCreateView
pour créer un projet :
from django.views.generic import CreateView
from .models import Project, Attachment
from .forms import ProjectForm
from django.urls import reverse_lazy
class ProjectCreateView(CreateView):
model = Project
form_class = ProjectForm
template_name = 'project_create.html'
success_url = reverse_lazy('project_list')
def form_valid(self, form):
response = super().form_valid(form) # Sauvegarde l'objet Project
attachments = self.request.FILES.getlist('attachments') # Récupère la liste des fichiers
for file in attachments:
attachment = Attachment.objects.create(file=file) # Crée un objet Attachment
self.object.attachments.add(attachment) # Lie le fichier au projet
return response
- Vue
TaskCreateView
pour créer une tâche :
from django.views.generic import CreateView
from .models import Task, Attachment
from .forms import TaskForm
from django.urls import reverse_lazy
class TaskCreateView(CreateView):
model = Task
form_class = TaskForm
template_name = 'task_create.html'
success_url = reverse_lazy('task_list')
def form_valid(self, form):
response = super().form_valid(form)
attachments = self.request.FILES.getlist('attachments')
for file in attachments:
attachment = Attachment.objects.create(file=file)
self.object.attachments.add(attachment)
return response
Explications :
getlist('attachments')
: Récupère tous les fichiers joints uploadés via le formulaire.self.object.attachments.add(attachment)
: Lie chaque fichier téléchargé à l'objetProject
ouTask
.
Étape 5 : Templates pour les formulaires
Objectif
Nous devons maintenant créer les templates HTML pour afficher les formulaires d'ajout de projets et de tâches avec des fichiers joints.
Implémentation
- Template pour créer un projet (
project_create.html
) :
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Créer le projet</button>
</form>
- Template pour créer une tâche (
task_create.html
) :
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Créer la tâche</button>
</form>
Explications :
enctype="multipart/form-data"
: Nécessaire pour permettre l'upload de fichiers dans le formulaire.{{ form.as_p }}
: Génère les champs du formulaire, y compris l'input pour l'upload de fichiers.
Étape 6 : Améliorations évolutives (Dropzone.js, etc.)
Objectif
Tu peux facilement ajouter Dropzone.js pour offrir une interface de glisser-déposer et de copier-coller pour les fichiers joints. Cela permet de rendre l'expérience utilisateur plus fluide, mais tu peux l'ajouter plus tard sans changer ta logique back-end.
-
Ajout de Dropzone.js : Suis l'exemple que nous avons vu précédemment pour intégrer Dropzone.js en tant qu'amélioration front-end.
-
Réutilisation du backend : La logique côté serveur ne change pas. Tu récupères toujours les fichiers via
self.request.FILES.getlist('attachments')
.
Résumé des étapes
- Modèle
Attachment
: Crée un modèle réutilisable pour gérer les fichiers. - Ajout du champ
ManyToManyField
dans les modèles : Relie le modèleAttachment
à d'autres modèles commeProject
ouTask
. - Création des formulaires : Gère l'upload de plusieurs fichiers dans des formulaires de type
ModelForm
. - Vues basées sur des classes : Implémente les vues pour traiter les fichiers joints lors de la création ou mise à jour d'un objet.
- Templates HTML : Gère l'upload via des formulaires simples, avec la possibilité d'ajouter Dropzone.js plus tard.
Ce guide te permet d'avoir une architecture robuste et évolutive pour gérer des fichiers joints dans plusieurs modèles, tout en offrant une base solide pour intégrer des améliorations front-end comme Dropzone.js ultérieurement.