一:什么是Form?什么是Django Form
Django的表單系統(tǒng)中,所有的表單類都作為django.forms.Form的子類創(chuàng)建,包括ModelForm
關(guān)于django的表單系統(tǒng),主要分為兩種:
- 基于django.forms.Form:所有表單類的父類
- 基于django.forms.ModelForm:可以和模型類綁定的Form
案例:實(shí)現(xiàn)添加出版社信息的功能
不使用Django Form的情況
建立urls映射,在views里添加邏輯代碼
if request.method == "POST":
# 如果是POST,接收用戶輸入
name = request.POST['name']
address = request.POST['address']
city = request.POST['city']
state_province = request.POST['state_province']
country = request.POST['country']
website = request.POST['website']
# 這里最好要做非空驗(yàn)證
Publisher.objects.create(
name=name,
address=address,
city=city,
state_province=state_province,
country=country,
website=website,
)
return HttpResponse("添加出版社信息成功")
else:
return render(request, "add.html", locals())
add.html 內(nèi)容
<form action="{% url 'add_publisher' %}" method="post">
{% csrf_token %}
名稱:<input type="text" name="name"><br>
地址:<input type="text" name="address"><br>
城市:<input type="text" name="city"><br>
省 :<input type="text" name="state_province"><br>
國家:<input type="text" name="country"><br>
網(wǎng)站:<input type="text" name="website"><br>
提交:<input type="submit" name="提交"><br>
使用Form的情況
在app里新建forms.py
,添加代碼:
from django import forms
class Publisher(forms.Form):
name = forms.CharField()
address = forms.CharField()
city = forms.CharField()
state_province = forms.CharField()
country = forms.CharField()
website = forms.URLField()
views代碼修改成:
from hello.forms import PublisherForm
if request.method == "POST":
# 如果是POST,接收用戶輸入
publisher_form = PublisherForm(request.POST)
# 表單驗(yàn)證
if publisher_form.is_valid():
# 這里最好要做非空驗(yàn)證
Publisher.objects.create(
name=publisher_form.cleaned_data['name'],
address=publisher_form.cleaned_data['address'],
city=publisher_form.cleaned_data['city'],
state_province=publisher_form.cleaned_data['state_province'],
country=publisher_form.cleaned_data['country'],
website=publisher_form.cleaned_data['website'],
)
return HttpResponse("添加出版社信息成功")
else:
publisher_form = PublisherForm()
return render(request, "add.html", locals())
實(shí)例化PublisherForm(),傳入模板中
模板簡化成:
<form action="{% url 'add_publisher' %}" method="post">
{% csrf_token %}
{{ publisher_form.as_p }}
提交:<input type="submit" name="提交"><br>
# as_p p標(biāo)簽 還有 as_table 還有as_ul
使用ModelForm的情況
首先forms簡化了
from django import forms
from hello.models import Publisher
class PublisherForm(forms.ModelForm):
class Meta:
model = Publisher
# fields設(shè)置綁定到forms的 exclude設(shè)置不綁定的
exclude = ("id", )
views也更簡單了
if request.method == "POST":
# 如果是POST,接收用戶輸入
publisher_form = PublisherForm(request.POST)
# 表單驗(yàn)證
if publisher_form.is_valid():
# 這里最好要做非空驗(yàn)證
publisher_form.save()
return HttpResponse("添加出版社信息成功")
else:
publisher_form = PublisherForm()
return render(request, "add.html", locals())
哈 少了很多~~~
總結(jié):Django Form可以大大簡化代碼,常用的表單功能特性都整合到了Form中,ModelForm可以和Model進(jìn)行綁定,更進(jìn)一步簡化代碼
關(guān)于Form的驗(yàn)證:
表單-->自定義驗(yàn)證
- 表單字段的驗(yàn)證器
- clean_filename,驗(yàn)證字段,針對(duì)某個(gè)字段進(jìn)行驗(yàn)證
- 表單clean方法,可針對(duì)整個(gè)表單進(jìn)行驗(yàn)證
案例:自定義驗(yàn)證,不能插入重復(fù)的出版社名稱
1.表單字段的驗(yàn)證器
from django import forms
from hello.models import Publisher
from django.core.exceptions import ValidationError
def validate_name(vaule):
try:
Publisher.objects.get(name=vaule)
raise ValidationError("%s的信息已經(jīng)存在" % vaule)
except Publisher.DoesNotExist:
pass
class PublisherForm(forms.ModelForm):
name = forms.CharField(label="名稱", validators=[validate_name])
class Meta:
model = Publisher
# fields設(shè)置綁定到forms的 exclude設(shè)置不綁定的
exclude = ("id", )
2. clean_filename,驗(yàn)證字段,針對(duì)某個(gè)字段進(jìn)行驗(yàn)證
class PublisherForm(forms.ModelForm):
def clean_name(self):
vaule = self.cleaned_data.get("name")
try:
Publisher.objects.get(name=vaule)
raise ValidationError("%s的信息已經(jīng)存在llllllllll" % vaule)
except Publisher.DoesNotExist:
pass
return value
class Meta:
model = Publisher
# fields設(shè)置綁定到forms的 exclude設(shè)置不綁定的
exclude = ("id", )
3. 表單clean方法,可針對(duì)整個(gè)表單進(jìn)行驗(yàn)證
class PublisherForm(forms.ModelForm):
def clean(self):
cleaned_data = super(PublisherForm, self).clean()
vaule1 = cleaned_data.get("name")
vaule2 = cleaned_data.get("address")
if vaule1 != vaule2:
self._errors['address'] = self.error_class(["信息不一致"])
return cleaned_data
class Meta:
model = Publisher
# fields設(shè)置綁定到forms的 exclude設(shè)置不綁定的
exclude = ("id", )