django—Form组件

Posted yamx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django—Form组件相关的知识,希望对你有一定的参考价值。

  django的Form组件主要实现的功能:

    1、渲染html代码(不用手写相关前端表单代码)

    2、校验数据

    3、展示提示信息

Form组件的定义

  以注册功能为例

  from django import forms
  class RegForm(forms.Form):
   user = forms.CharField()
  pwd = forms.CharField()

  一个功能的form组件是一个类,这个类必须继承forms中的Form类(和模型类定义的形式有点类似);

  这个类内部定义的成员变量就对应着前端页面的一个个input标签。

 

Form组件的基本使用

  1、在视图函数中

    def reg(request):
    form_obj = RegForm()
    return render(request, ‘reg.html‘, {‘form_obj‘: form_obj})

    只需要将Form类实例化,传给对应的前端页面完成渲染,即可展示相应的表单内容

  2、在模板文件中渲染

    由于form组件只提供表单内部的元素,不包含表单以及按钮。所以在模板文件中需要手写相关代码。

    <form action="" method="post">
    {% csrf_token %}
    {{ form_obj.as_p }}
    <button>注册</button>
    </form>

    以上代码在前端显示为

    技术图片

 

 

     form_obj.as_p:将每个元素以p标签形式渲染出来(p标签内部有label和input)

    

  3、标签渲染的方式

    a、以不同形式,自动将所有元素一次性渲染出来,不利于后续扩展。

     {{ form_obj.as_p }}

     {{ form_obj.as_ul }}

     {{ form_obj.as_table }} 

    b、根据from_obj内部的成员变量,手动生成想要的元素以及展示形式,扩展性高,代码冗余。

     <p>{{ form_obj.user.label }}:{{ form_obj.user }}</p>

     <p>{{ form_obj.pwd.label }}:{{ form_obj.pwd }}</p>

    c、利用for循环生成元素,扩展性高,代码精简。

     {% for form in form_obj %}

      <p>{{ form.label }}:{{ form }}</p>

     {% endfor %}

 

  4、校验数据

    后端要想使用Form组件进行数据的校验,首先需要关闭前端的校验(直接将数据给后端)

    只需要在from标签内加上novalidate属性即可

    后端校验数据:

    def reg(request):
    form_obj = RegForm() # 空的Form对象
    if request.method == ‘POST‘:
    form_obj = RegForm(request.POST) # 包含用户提交的数据的From对象
    if form_obj.is_valid(): # 对数据进行校验
    return HttpResponse(‘ok‘)
    # 如果校验不成功,那么render返回的form_obj中就包含了对应字段的错误信息,可以渲染在前端
    return render(request, ‘reg.html‘, {‘form_obj‘: form_obj})

    前端可以通过{{ form_obj.errors }}打印出所有的错误,也可以根据不同字段来打印错误信息{{ form_obj.user.errors }}

    如果某个字段有多个错误还可以通过下标的方式选择打印错误信息{{ form_obj.user.errors.0 }},否则是以列表的形式展示数据

    

    form组件会在数据不合法的情况下,保存上次的数据,让用户基于上次的数据进行修改。

Form常用的字段和参数

  1、常用字段

    Form组件可用的字段有:

    __all__ = (
    ‘Field‘, ‘CharField‘, ‘IntegerField‘,
    ‘DateField‘, ‘TimeField‘, ‘DateTimeField‘, ‘DurationField‘,
    ‘RegexField‘, ‘EmailField‘, ‘FileField‘, ‘ImageField‘, ‘URLField‘,
    ‘BooleanField‘, ‘NullBooleanField‘, ‘ChoiceField‘, ‘MultipleChoiceField‘,
    ‘ComboField‘, ‘MultiValueField‘, ‘FloatField‘, ‘DecimalField‘,
    ‘SplitDateTimeField‘, ‘GenericIPAddressField‘, ‘FilePathField‘,
    ‘SlugField‘, ‘TypedChoiceField‘, ‘TypedMultipleChoiceField‘, ‘UUIDField‘,
    )   

    CharField——文本输入框

    EmailField——邮箱文本输入框(输入的字段必须符合邮箱的格式)

    ChoiceField——单选框 默认是select

    MultipleChoiceField——多选框 默认是select

  2、字段参数

    initial——设置默认值

    error_messages——重写错误信息(默认错误信息是固定格式且是英文的) 

      error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
         }

    label——设置字段名,前端默认展示的字段名是首字母大写的成员变量名

    choices——设置选择框的选项,每个选项都以元组形式存储(存储在数据库的值,前端页面展示的值)

    required——设置字段是必填项

    disabled——设置input是否禁用

    validators——设置字段的校验器,对应值是一个列表,列表内存放函数对象,即相关校验函数。

    widget——插件,修改input的类型    

      widget=forms.PasswordInput(attrs={‘class‘:‘form-control c1 c2‘})

      修改input类型的同时还能够设置属性值

      可选的类型如下:   

        __all__ = (
        ‘Media‘, ‘MediaDefiningClass‘, ‘Widget‘, ‘TextInput‘, ‘NumberInput‘,
        ‘EmailInput‘, ‘URLInput‘, ‘PasswordInput‘, ‘HiddenInput‘,
        ‘MultipleHiddenInput‘, ‘FileInput‘, ‘ClearableFileInput‘, ‘Textarea‘,
        ‘DateInput‘, ‘DateTimeInput‘, ‘TimeInput‘, ‘CheckboxInput‘, ‘Select‘,
        ‘NullBooleanSelect‘, ‘SelectMultiple‘, ‘Radioselect‘,
        ‘CheckboxSelectMultiple‘, ‘MultiWidget‘, ‘SplitDateTimeWidget‘,
        ‘SplitHiddenDateTimeWidget‘, ‘SelectDateWidget‘,
        )

      通过修改CharField的类型,可以实现其他字段的效果。

          

  补充:

    前端展示选择框数据的时候,往往这些数据都是写死的。

    可以将选择框数据单独存放在表中,然后将该表的查询结果作为展示数据,这样前端展示选择框数据时就可以实现动态展示。

      首先需要导入   from django.forms import models  as form_model

        hobby = form_model.ModelMultipleChoiceField( queryset=models.Hobby.objects.all(), widgets=forms.CheckboxSelectMultiple)

 

校验方法

  1、设置校验器

    定义校验函数

    from django.core.exceptions import ValidationError
    def check_name(value):
    if ‘1‘ in value:
    raise ValidationError(‘该用户名不符合要求‘)

    在相应字段加上validators参数

    user = forms.CharField(label=‘用户名‘, validators=[check_name])

    校验函数内,出现不符合校验标准的情况必须抛出ValidationError异常,异常信息作为校验错误的提示信息

    技术图片

 

 

   2、定义钩子函数

    钩子函数需要定义在Form类当中

    a、局部钩子

      函数的命名为clean_字段名

      class RegForm(forms.Form):
      user = forms.CharField(label=‘用户名‘)
      pwd = forms.CharField(label=‘密码‘, widget=forms.PasswordInput())

      def clean_user(self):
      value = self.cleaned_data.get(‘user‘)
      if ‘1‘ in value: # 不符合校验规则
      raise ValidationError(‘该用户名不符合要求‘)
      # 符合校验规则
      return value

      cleaned_data是经过is_valid()校验过,没有问题的数据字典

      使用is_valid()方法前,没有cleaned_data字典,获取时会报错

      只有在is_valid()方法之后,才生成了cleaned_data字典

    b、全局钩子

      全局钩子命名为clean,针对所有字段

      def clean(self):
      username = self.cleaned_data.get(‘user‘)
      pwd = self.cleaned_data.get(‘pwd‘)
      if ‘1‘ in username: # 不符合校验规则
      raise ValidationError(‘该用户名不符合要求‘)
      if ‘1‘ in pwd:
      raise ValidationError(‘密码包含禁用词‘)
      # 符合校验规则 返回所有字段的值
      return self.cleaned_data

      此时,抛出的错误信息存放在全局{{ form_obj.errors }},不能通过字段名的错误信息获取到

      要想将错误信息存放在某个字段当中,可以通过以下方法:

        self.add_error(字段名,错误信息)

        self.add_error(‘pwd‘, ‘错误‘)

      注意:

        钩子函数中出现不符合校验规则的情况,必须要抛出异常。

        即便已经将某个错误信息存放到指定字段中,也需要抛出异常(固定搭配)

 

以上是关于django—Form组件的主要内容,如果未能解决你的问题,请参考以下文章

Django—分页器与form组件

Django框架之Form组件

Django Form 组件

Django高级-Form表单组件应用

Django(十五)Form组件

西游之路——python全栈——Django的form组件初识