Un evento completo
Parte de la sección Formularios del Journey de Django de Coddy. Lección 17 de 20.
La clase de cerámica tiene 2 plazas y 2 invitados, pero su formulario aún acepta más. La regla debe estar en el formulario, pero solo la vista sabe para qué evento es el formulario.
Un formulario es una clase de Python, así que puedes darle tu propio __init__. Toma el valor adicional como argumento de palabra clave, guárdalo en self y pasa el resto a super().__init__(). Un formulario de pujas que necesita el artículo de la subasta:
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 amountLa vista pasa el artículo cada vez que crea el formulario: BidForm(request.POST, item=item). Nombrar item en la firma evita que forme parte de **kwargs; el formulario de Django no lo conoce y generaría un TypeError.
Desafío
IntermedioLos eventos completos rechazan las confirmaciones de asistencia.
- En
events/forms.py, añade aRSVPFormun__init__que guarde el argumento con nombreeventenself.eventy pase el resto asuper().__init__. - En su
clean(), cuando se alcance lacapacityde invitados, genera el errorSorry, this event is full.. Si queda un lugar, todavía se acepta a un invitado. - En
event_detail, pasaeventa ambas llamadas aRSVPForm.
Confirma tu asistencia a la clase de cerámica: verás Sorry, this event is full.
Pruébalo tú mismo
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"]
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Formularios
2Formularios de Django
Un formulario de DjangoDibujar un formulario5Proyecto: Lista de invitados
Una confirmación de asistencia por correo electrónicoUna página para invitadosPractica por tu cuenta: Playground de Django