One RSVP per Email
Part of the Forms section of Coddy's Django journey. Lesson 18 of 20.
This chapter is yours: three features for the events board, built with what you know. Each task says what the site must do; the code is up to you.
Right now Ada can RSVP to Friday Jazz Night as often as she likes, and every RSVP takes a place. One email should hold one place per event.
You have every piece: a clean_<field> method, the event the form keeps in self.event, and its RSVPs in self.event.rsvps. One more lookup helps: email__iexact compares text without case, because Ada@Example.com and ada@example.com reach the same inbox.
Challenge
MediumRefuse a second RSVP from the same email to the same event, with This email is already on the guest list. under the email field.
- Capitals do not matter:
ADA@Example.comisada@example.com. - The same email can still RSVP to another event.
Press Run and RSVP twice to Friday Jazz Night with one email.
Try it yourself
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"]
def __init__(self, *args, event=None, **kwargs):
super().__init__(*args, **kwargs)
self.event = event
def clean(self):
cleaned_data = super().clean()
if self.event.rsvps.count() >= self.event.capacity:
raise forms.ValidationError("Sorry, this event is full.")
return cleaned_data
All lessons in Forms
Practice on your own: Django playground