美文网首页
Django学习笔记:Forms

Django学习笔记:Forms

作者: Py_Bird | 来源:发表于2018-12-24 13:53 被阅读0次

    表单介绍

    HTML表单负责接收用户的输入,对输入进行合法格式判断,并将数据发送到服务器。一个HTML表单必须指定两样东西:发送数据的url地址,发送的HTTP方法(GET、POST)。

    GET方法:将用户数据以?<键1>=<值1>&<键2>=<值2>&...形式拼接到url后面,通常用于请求数据、网页搜索的表单。

    POST方法:组合表单的数据并进行编码,然后打包发送到服务器,数据不会出现在url中,通常用于保密信息的发送、大量数据的表单、二进制数据。

    在input标签中

    #对于form表单也是一样,如果前端不指定post方法,默认使用get方法。

    表单字段(常用)

    CharField

    渲染类型:TextInput

    输入空值的返回:empty_value设定的值

    转换为对象:Unicode对象

    验证:min_length,max_length(如果设置过)

    可用的错误信息键:min_length,max_length,required

    max_length:允许输入的最大长度

    min_length:允许输入的最小长度

    strip:默认为True,表示去除前后的空格

    empty_value:输入为空时返回的值,默认为空字符串

    EmailField

    渲染类型:EmailInput

    输入空值的返回:空字符串

    转换为对象:Unicode对象

    验证:用正则表达式验证表单的值,必须是合法邮件地址

    可用的错误信息键:required,invalid

    max_length:允许输入的最大长度

    min_length:允许输入的最小长度

    表单字段的参数

    error_messages

    error_messages={‘key’: ‘value’}

    自定义错误提示信息,键是表单里同名的错误类型字符串,值是自定义的提示信息字符串。

    其中的key包括:

    required,无填写内容

    invalid,非法字符

    maxlength,超出长度上限

    max_length

    最大长度

    min_length

    最小长度

    required

    required=True/False

    该字段必填/非必填。

    当为True时,<表单对象>.clean(‘‘)和<表单对象>.clean(None)返回ValidationError异常。

    当为False时,<表单对象>.clean(‘‘)和<表单对象>.clean(None)返回None。

     

    label

    label=’<显示值>’

    字段渲染成HTML代码的提示词,默认在后面加冒号。

    如字段name = forms.CharField(label=’Your Name’),显示为HTML的

    <label for=”id_name”>Your name: </label>

    <input id=”id_name” type="text" name="name" required />

    label_suffix

    label_suffix=’<字符>’

    自定义字符,代替label生成显示值后面的冒号。

    initial

    initial=’<值>’

    为表单元素定义初始值,即标签中的value=,可传入值和对象。

    # initial不会作为数据提交,表单仍需要用户填写数据。

    只能用initial传递初始值,如果在渲染表单的时候传递一个初始值字典,会触发表单的验证,此时输出的HTML页面可能包含验证错误。

    widget

    widget=<widget类>

    指定渲染Widget时使用的widget类,即前端中的type类型。

    可用attr参数传入一个字典,对widget添加CSS样式,如:

    name = forms.CharField(widget=forms.TextInput(attrs={‘class’: ‘special’}) )

    comment = forms.CharField(widget=forms.TextInput(attrs={‘size’: ‘40’}) )

    help_text

    help_text=’<文本>’

    设定辅助性描述文本,相当于HTML的默认显示值。

    validators

    validators=[ ]

    传入列表,包含对字段验证的函数,自定义验证方法的时候用。

    localize

    实现表单数据输入的本地化。

    disabled

    disabled=True/False

    设置对字段禁用/启用编辑,禁用编辑后,即使非法篡改前端页面的属性向服务器提交,该字段值也会被忽略。

    表单API

    绑定数据的表单能够验证数据,然后生成HTML表单,未绑定的表单无法验证数据,可生成HTML空表单。

    创建空表单:f = <表单名>form()#创建表单类的实例

    表单绑定数据:data = {:}#字典键是表单的字段名,值是传入的数据

                              f = <表单名>form(data)

                              #传入空字典将创建一个数据为空的已绑定表单

    forms.Form实例的数据无法自读,所以创建表单对象之后不可更改。

    表单的绑定

    <表单对象>.is_bound

    判断表单是/否绑定了数据,返回True/False。

    表单的数据错误验证

    <表单对象>.is_valid()

    验证表单数据合法性,返回True/False。.is_valid()实际就是检查<表单对象>.errors是否为空,如果errors列表为空,就把所有数据储存到<表单对象>.cleaned_data字典中。

    <表单对象>.errors

    包含所有错误信息的字典类型,键是表单字段名,值是由错误信息组成的字符串形列表。

    <表单对象>.errors.as_data()

    返回错误信息的字典形式,将字段映射到原始的ValidationError实例,如:

    {'sender': [ValidationError(['Enter a valid email address.']) ],

    'subject': [ValidationError(['This field is required.']) ] }

    <表单对象>.errors.as_json()

    错误信息字典的JSON序列化形式,如:

    {"sender": [{"message": "Enter a valid email address.", "code": "invalid"}],

    "subject": [{"message": "This field is required.", "code": "required"}] }

    <表单对象>.add_error(<字段名>, <错误信息>)

    向表单的指定字段添加错误信息。

    <表单对象>.has_error(<字段>, code=xxx)

    判断某个字段是/否有指定的xxx错误,返回True/False。当code=None时,该字段有任何错误都返回True。

    <表单对象>.non_field_errors()

    返回<表单对象>.errors中不是与特定字段关联的错误。

     

    表单的cleaned_data数据

    ①如果数据验证通过,把所有数据储存到<表单对象>.cleaned_data字典中;如果数据验证不通过,只把合法的数据存到<表单对象>.cleaned_data字典中。

    ②cleaned_data只包含Form类中的字段,如果传递额外数据,将不被储存。

    ③传递的数据不包含Form类中的某字段,cleaned_data中依然包含该键值对,显示为空值。

    表单的数据更改验证

    <表单对象>.has_changed()

    检查表单数据是否从初始值发生改变,有改变返回True,无改变返回False,如:

    data = <字典>

    f = ContactForm(request.POST, initial=data)      # POST和data内容不一样

    f.has_changed()

    <表单对象>.changed_data

    返回表单中有数据变化的字段的列表,如:

    f = ContactForm(request.POST, initial=data)      # POST和data内容不一样

    print(“, “.join(f.changed_data) )

    表单的HTML生成

    form类不包含<form></form>标签和<input type=”submit”>提交按钮,为方便开发人员自行编写控制表单动作和CSS,JS及如bootstrap框架的嵌入。

    生成HTML标签的就是表单字段名,每个字段类型都由一个默认的HTML标签展示,可用widget参数指定生成的类型。

    表单自动为每个input元素设置一个,用于的for参数。

    {{ form.as_p }}

    将每个字段渲染成标签。

    {{ form.as_ul }}

    将每个字段渲染成

    标签(无序),

      标签需自己指定。

      {{ form.as_table }}

      将表单的每个字段渲染成标签,标签需自己指定。

      表单字段在前端的属性

      {{ field.value }}       当前字段的值,比如一个Email字段的值:someone@example.com

      {{ field.errors }}      包含错误信息的元素

      {{ field.label }}    字段的label信息

      {{ field.id_for_label }} 自定义字段标签的id

      {{ field.html_name }} 指定字段生成的input标签中name属性的值

      {{ field.help_text }} 字段的帮助信息

      {{ field.is_hidden }} 用于判断当前字段是否为隐藏的字段,隐藏则返回True

      {{ field.field }}      返回字段的参数列表,例如{{ char_field.field.max_length }}

      表单错误信息的CSS样式

      class <表单名>FORM(forms.Form):

          error_css_class = ‘error’

          required_css_class = ‘required’

          #其它表单字段...

      以后这个表单渲染HTML时将自动为error行和required行添加对应的CSS样式。

      表单上传文件

      没看懂,略。。。

      模型表单ModelForm

      基于model模型创建的表单,对模型的字段进行重用,根据model字段的限制进行表单验证。

      验证后,ModelForm.save()实际就是调用Model.save(),直接保存到数据库。

      from django.forms import ModelForm

      from <应用名>.models import <类>

      class <类名>Form(ModelForm):       #继承于ModelForm类

          class Meta:                     #设置元类Meta

              model = <类>               #设置model属性为某个模型类

              fields = [<字段1>, <字段2>, ...]      #用field属性传入列表,指定类中的字段

              fields = ‘__all__’                    #也可用field属性传入类的全部字段

              exclude = [<字段1>, <字段2>, ...]     #用exclude属性将排除的字段之外全部传入

      模型表单的保存

      <模型表单对象>.save(commit=True)       #将form表单的内容提交到数据库并保存

      如果没有commit=True就只提交,不保存

      指定数据对象

      form = ModelForm(instance=<绑定的Model对象>)

      此时可以直接form.save()将表单数据保存到数据表中。

      #如果不指定某个对象,save()时会在数据表中新增一行数据

      模型字段对应表单字段

      Model                           Form

      AutoField                        无对应

      BigAutoField                     无对应

      BigIntegerField                   IntegerField

      CharField                        相同,如果model设置null=True,Form将使用empty_value

      CommaSeparatedIntegerField      CharField

      ForeignKey                       ModelChoiceField

      ManyToManyField                 ModelMultipleChoiceField

      PositiveIntegerField                IntegerField

      PositiveSmallIntegerField           IntegerField

      SmallIntegerField                  IntegerField

      TextField                          CharField,属性widget=forms.Textarea

      模型字段设置blank=True属性,表单字段将设置required=False,反之相反。

      模型字段的verbose_name属性会设为表单字段的label属性,并将第一个字母大写。

      模型字段设置editable=False属性,表单类中将不会出现该字段,因为该字段不可编辑。

      模型字段的help_text属性即为表单字段的help_text属性。

      模型字段设置choices参数,表单字段的widget属性将设置为Select,其选项和模型字段相同。表单选项中通常会包含一个空选项作为默认,如果该字段必选,会强制用户选择一个选项;如果模型字段具有default参数,就不会在表单选项中添加空选项。

      模型表单的验证

      用.is_valid()方法或查询.errors列表,也可以重写模型表单的def clean()方法进行额外的验证,如:

      class <类名>Form(ModelForm):

          class meta:

              # ...

      def clean_<函数名>(self):

          #验证self.cleaned_data字典的数据...

          return <数据>

      自定义ModelForm字段

      使用元类Meta的widgets属性:

      class <类名>Form(ModelForm):

          class Meta:

              model = <类>

              fields = [‘<字段1>’, ...]

              widgets = {                        #传入字典,键是模型字段名,值是自定义的内容

                  ‘<字段1>’:Textarea(attrs={‘cols’:80, ‘rows’:20} ),

                  ...

              }

      ModelForm字段的本地化

      使用Meta类的localized_fields属性,传入一个元组,指定本地化的字段:

      class <类名>Form(ModelForm):

      class meta:

          model = <类>

          localized_fields = (‘<字段1>’, ...)       #传入’__all__’表示将类中的所有字段本地化

      表单示例

      ①在forms.py中:

      from django import forms

      class <表单名>Form(forms.Form):     #所有表单继承于forms.Form类

          sender = forms.EmailField()

          name = forms.CharField(label=’Your Name’, max_length=100)

          #一个字段代表中的一个元素,字段负责验证和转换数据

          # label用于设置说明标签,这里的max_length同时限制前端和后端的输入长度

      ②在views.py中:

      from .forms import <表单名>Form

      def get_name(request):

          if request.method == ’POST’:          #对于POST方法发送数据,接收数据并验证、处理

          a_form = <表单名>Form(request.POST)

          #用request.POST字典构造forms.Form类实例,将所有数据加载到表单中

              if a_form.is_valid():

                  #处理表单数据...

                  return HttpResponseRedirect(‘/xxx/’)    #处理成功,重定向到一个新url

          if request.method == ’GET’:                 #对于GET方法请求数据,返回空表单到模板

              a_form = <表单名>Form()

          return render(request, ‘xxx.html’, {‘form’: a_form}

      #处理不成功时,给用户返回这个模板。如果数据不合法,逻辑会在if a_form.is_valid()处断开,

      此时的a_form是包含原数据的表单,方便用户修改

      ③在templates中:

      <form action="/xxx/" method="post">          #写标签

          {% csrf_token %}

          {{ form }}                                 #表单模型生成的form表单元素

          <input type="submit" value="Submit" />      #写提交按钮

      </form>

      {{ form.<字段名> }}              获取表单的字段内容,用于手动渲染表单

      {{ form.<字段名>.label_tag }}      生成<label>标签,用于手动渲染表单

      {{ form.hidden_fields }}           表单中的不可见字段的集合

      {{ form.visible_fields }}            表单中的可见字段的集合

      表单模板的重用

      将表单模板保存为一个独立HTML文件,然后用{% include %}引用:

      {% include ‘xxxform.html’ %}

      {% for field in form %}

          #处理字段...

      {% endfor %}

      用with参数给表单取别名,防止名称冲突:

      {% include ‘xxxform.html’ with form=<别名> %}

      {% for field in <别名> %}

          #处理字段...

      {% endfor %}

      相关文章

        网友评论

            本文标题:Django学习笔记:Forms

            本文链接:https://www.haomeiwen.com/subject/hffzkqtx.html