Hướng dẫn xây dựng Django forms cơ bản (P3)
Các phần trước mình đã nói qua sơ lược về form cũng như là cách làm việc với form trong Django. Và bài viết hôm nay sẽ hướng dẫn sâu hơn về cách xây dựng form đối với Django.
Hôm nay chúng ta có khái niệm tập biểu mẫu - tập các form là một lớp trừu tượng giúp làm việc với nhiều biểu mẫu trên cùng một trang. Giả sử như bạn có đoạn mã sau:
>>> from django import forms
>>> class ArticleForm(forms.Form):
... title = forms.CharField()
... pub_date = forms.DateField()
Và giờ nếu bạn muốn tạo nhiều bài viết, trang trong cùng một lúc thì có thể làm như sau:
>>\> from django.forms import formset_factory
>>\> ArticleFormSet = formset_factory(ArticleForm)
Với đoạn mã trên thì bạn đã tạo một lớp định dạng có tên ArticleFormSet
. Và việc bạn khởi tạo bộ định dạng sẽ cung cấp cho bạn khả năng dùng được lại các form và hiển thị chúng như form thông thường:
>>> formset = ArticleFormSet()
>>> for form in formset:
... print(form.as_table())
<tr><th><label for="id\_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id\_form-0-title"></td></tr>
<tr><th><label for="id\_form-0-pub\_date">Pub date:</label></th><td><input type="text" name="form-0-pub\_date" id="id\_form-0-pub_date"></td></tr>
Đối với form thì dữ liệu đầu vào sẽ quyết định được số lượng các form phụ, các chức năng của từng form và formset. Như ví dụ sau có tổng cộng ba form hiển thị: một cái cho dữ liệu ban đầu đã chuyển vào và kèm theo hai cái biểu mẫu bổ sung.
>>> import datetime
>>> from django.forms import formset_factory
>>> from myapp.forms import ArticleForm
>>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
>>> formset = ArticleFormSet(initial=\[
... {'title': 'Django is now open source',
... 'pub_date': datetime.date.today(),}
... \])
>>> for form in formset:
... print(form.as_table())
<tr><th><label for="id\_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id\_form-0-title"></td></tr>
<tr><th><label for="id\_form-0-pub\_date">Pub date:</label></th><td><input type="text" name="form-0-pub\_date" value="2008-05-12" id="id\_form-0-pub_date"></td></tr>
<tr><th><label for="id\_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" id="id\_form-1-title"></td></tr>
<tr><th><label for="id\_form-1-pub\_date">Pub date:</label></th><td><input type="text" name="form-1-pub\_date" id="id\_form-1-pub_date"></td></tr>
<tr><th><label for="id\_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id\_form-2-title"></td></tr>
<tr><th><label for="id\_form-2-pub\_date">Pub date:</label></th><td><input type="text" name="form-2-pub\_date" id="id\_form-2-pub_date"></td></tr>
absolute_max
với formset_factory()
cho phép giới hạn số lượng biểu mẫu có thể được khởi tạo khi cung cấp POST
- dữ liệu đầu vào. Điều này còn có thể giúp bảo vệ và chống lại các cuộc tấn công làm đầy bộ nhớ:
>>> from django.forms.formsets import formset_factory
>>> from myapp.forms import ArticleForm
>>> ArticleFormSet = formset\_factory(ArticleForm, absolute\_max=1500)
>>> data = {
... 'form-TOTAL_FORMS': '1501',
... 'form-INITIAL_FORMS': '0',
... }
>>> formset = ArticleFormSet(data)
>>> len(formset.forms)
1500
>>> formset.is_valid()
False
>>> formset.non\_form\_errors()
\['Please submit at most 1000 forms.'\]
absolute_max
là None
thì nó sẽ mặc định: max_num + 1000
max_num``None``2000
.