--- title: Django author: Steve Kossouho --- # Utiliser des formulaires avec la base de données ---- ## Définition de formulaires basés sur les modèles ### Qu'est-ce qu'un `ModelForm` ? Un `ModelForm` est une classe spéciale de formulaire dans Django qui génère automatiquement un formulaire à partir d'un modèle spécifié. ```python from django import forms from .models import MonModel class MonModelForm(forms.ModelForm): class Meta: model = MonModel fields = '__all__' ``` Ici, un formulaire est créé pour le modèle `MonModel`. L'option `fields = '__all__'` signifie que tous les champs du modèle sont inclus dans le formulaire. ---- ## Utilisation des formulaires et validation ---- ### Utilisation de `ModelForm` dans une vue Un `ModelForm` peut être utilisé dans une vue de la même manière qu'un formulaire normal. Voici un exemple de vue qui utilise un `ModelForm`. ```python from django.shortcuts import render from .forms import MonModelForm def ma_vue(request): if request.method == 'POST': form = MonModelForm(request.POST) if form.is_valid(): form.save() else: form = MonModelForm() return render(request, 'ma_template.html', {'form': form}) ``` Dans cet exemple, si la requête est une requête POST et que le formulaire est valide, le modèle associé est automatiquement enregistré en base de données grâce à la méthode `form.save()`. ---- ## Gestion des téléchargements ---- ### Téléchargements de fichiers avec `ModelForm` Pour gérer le téléchargement de fichiers avec un `ModelForm`, il est nécessaire d'utiliser un champ `FileField` ou `ImageField` dans le modèle. Il faut également passer `request.FILES` à l'instance `ModelForm`. ```python class MonModel(models.Model): mon_fichier = models.FileField(upload_to='mes_fichiers/') # Dans la vue def ma_vue(request): if request.method == 'POST': form = MonModelForm(request.POST, request.FILES) if form.is_valid(): form.save() else: form = MonModelForm() return render(request, 'ma_template.html', {'form': form}) ``` Ici, si un fichier est téléchargé via le formulaire, il est automatiquement sauvegardé dans le répertoire `mes_fichiers/`. ---- # Utiliser des formulaires avec la base de données Utiliser des formulaires qui correspondent à nos définitions de modèles est assez simple. Il suffit de créer une classe héritant de `django.forms.ModelForm`. Le formulaire correspondant contient automatiquement des champs reflétant ceux de notre modèle. ---- ## Définition de formulaires basés sur les modèles ![Définition d'un formulaire de modèle](assets/images/modelforms-definition.png) ---- ## Utilisation des formulaires et validation L'utilisation des formulaires de modèles ressemble beaucoup à l'utilisation de formulaires standard. Il existe toutefois quelques différences, notamment pour la gestion de l'enregistrement de données et la modification de données existantes. ---- ![Utilisation du formulaire non lié à un objet](assets/images/modelforms-new-instance.png) ---- ![Utilisation du formulaire lié à un objet](assets/images/modelforms-bind-instance.png) ---- ## Gestion des téléchargements Lorsque vous souhaitez gérer des téléchargements de fichier, vous devriez configurer deux paramètres dans votre projet, qui sont : - Le répertoire des fichiers média : `MEDIA_ROOT` - L'URL de base pour les afficher, `MEDIA_URL` (par défaut `"/media/"`) - Configurer les URLs pour servir des fichiers média : - Ajouter `+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)` aux URLs du projet pour servir les fichiers (ne fonctionne pas si `DEBUG = False` - Avoir un formulaire HTML avec la méthode `POST` et le type d'encodage `enctype="multipart/form-data"`. Sans `MEDIA_ROOT`, les fichiers seront uploadés et sauvés à la racine de votre projet (même pas dans un répertoire `media`), ce qui est fortement déconseillé. ---- L'avantage par rapport aux formulaires standard est que la gestion du téléchargement des fichiers se fait automatiquement lorsque vous persistez vos données de formulaire en faisant ```python form = MyForm(request.POST, request.FILES, instance=my_instance) # notez le request.FILES form.save(commit=True) ``` ---- Lorsque votre modèle possède des champs fichier, vous pouvez facilement accéder à l'URL du fichier uploadé en utilisant la propriété `url` du champ `FileField` ou `ImageField` : ```djangotemplate {{ item.picture_field.url }} {# URL commençant par settings.MEDIA_URL #} ```