zoukankan      html  css  js  c++  java
  • 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位"
             }

          也可以不设置error_messages,直接将settings里的LANGUAGE_CODE设置成'zh-hans',这样所有错误信息都可以中文显示

        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', '错误')

          注意:

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

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

       

    ModelForm

      ModelForm就是model和form的结合。

      原本在定义form类的时候,需要自己表单中的字段元素。

      有时候可以根据model类中定义好的字段来生成相应表单,如用户信息(账号密码)。

      1、定义 

      class RegForm(forms.ModelForm):
      
        class Meta:
         model = User
        fields = '__all__'
        widgets = {
          'username': forms.TextInput(attrs={'class': 'lowin-input'}),
        'pwd': forms.PasswordInput(attrs={'class': 'lowin-input'}),
        }
        error_messages = {
         'username': {
         'required': '用户名不能为空',
        'unique': '用户名已存在,请重新输入',
        },
        'pwd': {
         'required': '密码不能为空',
        },
        }

        class Meta中的参数说明: 

          model = models.User  # 对应的Model中的类
          fields = "__all__"  # 字段,如果是__all__,说明model类中的所有字段都将被用于生成表单
          exclude = None  # 排除的字段,排除掉的字段,不会生成在表单中
          labels = None  # 提示信息
          help_texts = None  # 帮助提示信息
          widgets = None  # 自定义插件
          error_messages = None  # 自定义错误信息

     

      2、使用方式和Form基本一致

        ModelForm对象有一个save方法,可以直接将接收到的有效数据保存到数据库中。

        前提的是:

          该ModelForm对象不是空对象,必须用接收到的数据初始化  

          form_obj = RegForm(request.POST)
          if form_obj.is_valid():
          form_obj.save()
          return HttpResponse('ok')

      3、调整form中字段显示的先后顺序

        在class Meta中,将fields的值改成列表,列表中字段的先后顺序,就是前端for循环的迭代的先后顺序

        如:

          fields = ['username', 'password', 're_password', 'mobile_phone', 'code']
  • 相关阅读:
    dada的GCD
    涛神的城堡
    手机信号
    涛涛的Party
    壮壮的数组
    不安全字符串
    gdb core 调试多线程
    makefile $@, $^, $<, $? 表示的意义
    KMP算法的next[]数组通俗解释
    【原创】支持同时生成多个main函数 makefile 模板
  • 原文地址:https://www.cnblogs.com/yamx/p/13338298.html
Copyright © 2011-2022 走看看