Menu
CoddyTech

Un événement complet

Fait partie de la section Formulaires du Journey Django de Coddy. Leçon 17 sur 20.

Le cours de poterie a 2 places et 2 invités, et pourtant son formulaire en accepte davantage. La règle doit être définie dans le formulaire, mais seule la vue sait à quel événement le formulaire est destiné.

Un formulaire est une classe Python : tu peux donc lui définir son propre __init__. Reçois la valeur supplémentaire comme argument nommé, conserve-la dans self et transmets les autres arguments à super().__init__(). Un formulaire d’enchère qui a besoin de l’article mis aux enchères :

class BidForm(forms.Form):
    amount = forms.IntegerField()

    def __init__(self, *args, item=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.item = item

    def clean_amount(self):
        amount = self.cleaned_data["amount"]
        if amount <= self.item.top_bid:
            raise forms.ValidationError("Bid more than the top bid.")
        return amount

La vue transmet l’article chaque fois qu’elle crée le formulaire : BidForm(request.POST, item=item). Nommer item dans la signature l’empêche de se retrouver dans **kwargs ; le formulaire Django ne le connaît pas et déclencherait une TypeError.

challenge icon

Défi

Moyen

Les événements complets refusent les inscriptions.

  1. Dans events/forms.py, ajoute à RSVPForm une méthode __init__ qui conserve l’argument nommé event dans self.event et transmet les autres arguments à super().__init__.
  2. Dans sa méthode clean(), lorsque le nombre de personnes atteint la capacity, déclenche l’erreur Sorry, this event is full. S’il reste une place, une personne peut encore s’inscrire.
  3. Dans event_detail, transmets event aux deux appels à RSVPForm.

Inscris-toi au cours de poterie : tu vois Sorry, this event is full.

Essayez vous-même

import datetime

from django import forms

from .models import RSVP, Event


class EventForm(forms.ModelForm):
    class Meta:
        model = Event
        fields = ["title", "date", "end_date", "place", "description", "capacity"]

    def clean_date(self):
        date = self.cleaned_data["date"]
        if date < datetime.date.today():
            raise forms.ValidationError("The date cannot be in the past.")
        return date

    def clean(self):
        cleaned_data = super().clean()
        date = cleaned_data.get("date")
        end_date = cleaned_data.get("end_date")
        if date and end_date and end_date < date:
            raise forms.ValidationError("The event cannot end before it starts.")
        return cleaned_data


class RSVPForm(forms.ModelForm):
    class Meta:
        model = RSVP
        fields = ["name", "email"]
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Formulaires

Entraînez-vous par vous-même : Playground Django