Một ModelForm
Thuộc phần Biểu mẫu trong hành trình Django của Coddy. Bài học 12 trên 20.
Hãy xem EventForm và model Event cạnh nhau: cùng một bộ trường được viết hai lần. ModelForm tạo các trường từ model. Với model Book:
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ["title", "author", "pages"]Lớp Meta bên trong chỉ định model và các trường cần dùng. Mỗi trường của model trở thành trường tương ứng trong form, còn blank=True khiến trường đó không bắt buộc. Danh sách này là bắt buộc, vì vậy một trường được thêm vào model sau này sẽ không vô tình xuất hiện trong form công khai.
clean_<field>() và clean() hoạt động tương tự khi đặt cạnh Meta. Form cũng tự lưu: form.save() tạo một hàng từ cleaned_data rồi trả về hàng đó.
Thử thách
DễChuyển EventForm thành ModelForm.
- Trong
events/forms.py, xóa sáu dòng trường và thêm mộtMetachỉ địnhEventcùng sáu trường:title,date,end_date,place,description,capacity. Giữ lạiclean_date()vàclean(). - Trong
new_event, thayEvent.objects.create()bằngform.save().
Thêm một sự kiện có ngày trong quá khứ: bạn vẫn thấy The date cannot be in the past.
Tự làm thử
import datetime
from django import forms
class EventForm(forms.Form):
title = forms.CharField(max_length=100)
date = forms.DateField()
end_date = forms.DateField(required=False)
place = forms.CharField(max_length=100)
description = forms.CharField(widget=forms.Textarea, required=False)
capacity = forms.IntegerField(min_value=1)
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
Tất cả bài học trong Biểu mẫu
Tự luyện tập: Playground Django