10 Form表單

一:什么是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)證

  1. 表單字段的驗(yàn)證器
  2. clean_filename,驗(yàn)證字段,針對(duì)某個(gè)字段進(jìn)行驗(yàn)證
  3. 表單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", )

由于clean方法是獲取的全部的數(shù)據(jù),所有對(duì)于判斷表單中關(guān)系的的字段 尤其好用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容