Một sự kiện hoàn chỉnh
Thuộc phần Biểu mẫu trong hành trình Django của Coddy. Bài học 17 trên 20.
Lớp làm đồ gốm có 2 chỗ và 2 khách, nhưng biểu mẫu vẫn nhận thêm khách. Quy tắc này thuộc về biểu mẫu, nhưng chỉ view mới biết biểu mẫu dành cho sự kiện nào.
Biểu mẫu là một lớp Python, nên bạn có thể tự viết __init__. Nhận giá trị bổ sung dưới dạng đối số từ khóa, lưu giá trị đó vào self và truyền phần còn lại cho super().__init__(). Biểu mẫu đặt giá cần có món đồ đấu giá:
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 amountView truyền món đồ mỗi lần tạo biểu mẫu: BidForm(request.POST, item=item). Khai báo item trong chữ ký hàm giúp giữ nó ngoài **kwargs; biểu mẫu của Django không biết tham số này và sẽ phát sinh TypeError.
Thử thách
Trung bìnhSự kiện đã kín chỗ sẽ từ chối đăng ký tham dự.
- Trong
events/forms.py, thêm choRSVPFormmột__init__để lưu tham số từ khóaeventvàoself.eventvà chuyển các tham số còn lại chosuper().__init__. - Trong
clean()của lớp này, khi khách lấp đầycapacity, hãy phát sinh lỗiSorry, this event is full.Nếu còn một chỗ, khách vẫn có thể đăng ký. - Trong
event_detail, truyềneventvào cả hai lần gọiRSVPForm.
Đăng ký tham dự lớp học làm gốm: bạn sẽ thấy Sorry, this event is full.
Tự làm thử
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"]
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Biểu mẫu
Tự luyện tập: Playground Django