Biểu mẫu chỉ là một công cụ để đơn giản hóa và tăng tốc (phát triển) quy trình tìm nạp dữ liệu POST từ yêu cầu. Một cách thủ công sẽ là làm request.POST.get('somefield')
cho tất cả các trường có trong một số biểu mẫu HTML. Nhưng Django có thể làm tốt hơn thế ...
Về bản chất của nó, một lớp Mẫu nắm giữ một số lĩnh vực và thực hiện các nhiệm vụ: đầu vào HTML
- hiển thị,
- thu thập và xác nhận dữ liệu khi sử dụng gửi nó,
- nếu các trường không xác thực, trả lại giá trị cùng với thông báo lỗi cho HTML,
- nếu tất cả các trường xác thực, cung cấp từ điển thuận tiện để truy cập các giá trị này trong chế độ xem.
Với các giá trị này, sau đó tôi có thể tạo thủ công một phiên bản mới MyModel
và lưu nó. Tất nhiên, tôi sẽ phải xác định một trường trong biểu mẫu cho mọi trường trong mô hình MyModel.
Điều này có nghĩa rằng, về cơ bản, tôi thể làm điều gì đó như thế này:
(tha thứ cho tôi vì đã không kiểm tra mã này, vì vậy tôi không thể xác rằng đó là chính xác 100%)
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class FormForMyModel(forms.Form):
form_field1 = forms.CharField(max_length=40, required=True)
form_field2 = forms.CharField(max_length=60, required=False)
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = FormForMyModel(request.POST)
if form.is_valid():
my_model = MyModel()
my_model.field1 = form.cleaned_data.get('form_field1', 'default1')
my_model.field2 = form.cleaned_data.get('form_field2', 'default2')
my_model.save()
else:
form = FormForMyModel()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
(điều này có thể được viết với một vài dòng mã ít hơn, nhưng điều đó có nghĩa là càng rõ ràng càng tốt)
Lưu ý rằng không có mối quan hệ nào giữa các trường Mô hình và trường Mẫu! Chúng ta phải gán giá trị bằng tay cho cá thể MyModel khi tạo nó.
Ví dụ trên phác thảo luồng công việc biểu mẫu chung. Nó thường là cần thiết trong các tình huống phức tạp, nhưng không phải trong một tình huống đơn giản như ví dụ này.
Ví dụ này (và rất nhiều ví dụ thực tế), Django có thể làm tốt hơn thế ...
Bạn có thể nhận thấy hai vấn đề gây phiền nhiễu trong ví dụ trên:
- Tôi có để xác định các trường trên
MyModel
và các trường trên FormForMyModel
riêng biệt. Tuy nhiên, có rất nhiều điểm giống nhau giữa hai nhóm (loại) của trường, vì vậy đó là loại công việc trùng lặp. Sự tương tự tăng lên khi thêm nhãn, trình xác thực, v.v.
- tạo
MyModel
thể hiện hơi ngớ ngẩn, phải gán tất cả các giá trị đó theo cách thủ công.
Đây là nơi mà một ModelForm do thỏa thuận.
Những hành động về cơ bản giống như một hình thức thường xuyên (trên thực tế, họ được mở rộng từ hình thức bình thường), nhưng họ có thể tiết kiệm cho tôi một số công việc (cả hai vấn đề tôi vạch ra, tất nhiên :)).
Vì vậy, trở lại hai vấn đề:
Thay vì xác định một hình thức Dòng cho mỗi mô hình Field, tôi chỉ cần xác định model = MyModel
trong lớp Meta
. Điều này hướng dẫn Biểu mẫu tự động tạo biểu mẫu Các trường từ các trường mô hình.
Mẫu biểu mẫu có phương thức save
. Điều này có thể được sử dụng để tạo cá thể mô hình trong một dòng trong chế độ xem, thay vì gán trường theo trường theo cách thủ công.
Vì vậy, cho phép thực hiện ví dụ trên với một ModelForm
:
models.py:
class MyModel(models.Model):
field1 = models.CharField(max_length=40, blank=False, null=False)
field2 = models.CharField(max_length=60, blank=True, null=True)
forms.py:
class MyModelForm(forms.ModelForm): # extending ModelForm, not Form as before
class Meta:
model = MyModel
views.py:
def create_a_my_model(request):
if request.method == 'POST':
form = MyModelForm(request.POST)
if form.is_valid():
# save the model to database, directly from the form:
my_model = form.save() # reference to my_model is often not needed at all, a simple form.save() is ok
# alternatively:
# my_model = form.save(commit=False) # create model, but don't save to database
# my.model.something = whatever # if I need to do something before saving it
# my.model.save()
else:
form = MyModelForm()
context_data = {'form': form}
return HttpResponse('templtate.html', context_data)
Hy vọng điều này đã xóa bỏ việc sử dụng Django tạo thành một chút.
Chỉ cần thêm một lưu ý - hoàn toàn ổn định để xác định trường Trường trên ModelForm
. Chúng sẽ không được sử dụng trong form.save()
nhưng vẫn có thể truy cập với form.cleaned_data
giống như trong Biểu mẫu thông thường.
đọc hướng dẫn https://docs.djangoproject.com/en/dev/intro/tutorial04/?from=olddocs/ và https://docs.djangoproject.com/en/dev/topics/forms/?from = olddocs. –
Tôi đã nhìn thấy cả hai bài báo này và tôi sẽ đọc lại lần nữa .. Tôi đã hy vọng hiểu được mối quan hệ giữa biểu mẫu, lượt xem và mẫu và cách tạo danh sách thả xuống .. Tôi cho rằng có thể nó sẽ đưa tôi thời gian để tiêu hóa .. nếu bất cứ ai khác có thể dành thời gian giải thích điều này, tôi sẽ rất hạnh phúc! – Oli