Django之Form组件

新手上路

Django的Form主要具备一下几大功能:javascript

  • 生成HTML标签
  • 验证用户数据(显示错误信息)
  • HTML Form提交保留上次提交数据
  • 初始化页面显示内容

经过Form验证有俩种形式html

  • Form表单提交

    验证、并能够保留上次内容java

  • Ajax提交

    验证、无需上次内容(Ajax提交数据页面不会刷新)python

    返回HttpResponsegit

    前面根据回调函数值相应地作出跳转或者显示错误信息正则表达式

小试牛刀

一、建立Form类数据库

二、View函数django

三、Html生成函数

初露锋芒

建立Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;post

一、Django中Form类内置字段以下:

经常使用字段

详细字段

二、Django内置插件

三、经常使用选择插件

展露头角

单选或者多选时、数据源是否能够实时更新、、、

在使用选择标签时,须要注意choices的选项能够从数据库中获取,可是因为是静态字段 ***获取的值没法实时更新***,那么须要自定义构造方法从而达到此目的。

方式1、

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
  
class MyForm(Form):
  
     user = fields.ChoiceField(
         # choices=((1, '上海'), (2, '北京'),),
         initial = 2 ,
         widget = widgets.Select
     )
  
     def __init__( self , * args, * * kwargs):
         super (MyForm, self ).__init__( * args, * * kwargs)
         # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
         # 或
         self .fields[ 'user' ].widget.choices = models.Classes.objects. all ().value_list( 'id' , 'caption' )

方式2、

使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现

?
1
2
3
4
5
6
7
8
9
10
from django import forms
from django.forms import fields
from django.forms import widgets
from django.forms import models as form_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
  
class FInfo(forms.Form):
     authors = form_model.ModelMultipleChoiceField(queryset = models.NNewType.objects. all ())
     # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

更上一层楼

经过上述,Django的Form组件提供验证用户提交的数据并能够显示错误信息(或自定制),更能能够生成相应的Html代码。更是猜测到,仅仅根据Form组件的验证或许知足不了一些需求,因而创建再Form的验证功能上使其有很强的扩展性

1、基于Form组件的字段上的简单扩展

方式A

?
1
2
3
4
5
6
7
8
9
10
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
 
class MyForm(Form):
     phone = fields.CharField(
         validators = [RegexValidator(r '^[0-9]+$' , '请输入数字' ), RegexValidator(r '^188[0-9]+$' , '数字必须以188开头' )],
     )

方式B

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.exceptions import ValidationError
  
  
# 自定义验证规则
def mobile_validate(value):
     mobile_re = re. compile (r '^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$' )
     if not mobile_re.match(value):
         raise ValidationError( '手机号码格式错误' )
  
  
class PublishForm(Form):
  
  
     title = fields.CharField(max_length = 20 ,
                             min_length = 5 ,
                             error_messages = { 'required' : '标题不能为空' ,
                                             'min_length' : '标题最少为5个字符' ,
                                             'max_length' : '标题最多为20个字符' },
                             widget = widgets.TextInput(attrs = { 'class' : "form-control" ,
                                                           'placeholder' : '标题5-20个字符' }))
  
  
     # 使用自定义验证规则
     phone = fields.CharField(validators = [mobile_validate, ],
                             error_messages = { 'required' : '手机不能为空' },
                             widget = widgets.TextInput(attrs = { 'class' : "form-control" ,
                                                           'placeholder' : u '手机号码' }))
  
     email = fields.EmailField(required = False ,
                             error_messages = { 'required' : u '邮箱不能为空' , 'invalid' : u '邮箱格式错误' },
                             widget = widgets.TextInput(attrs = { 'class' : "form-control" , 'placeholder' : u '邮箱' }))

2、基于源码执行的流程上进行扩展

方式A

例如在注册一个帐号时、经过Form的验证其帐号符合规则时,还将要判断该帐号是否存在于数据库,如存在则确定是注册不经过的

自定义方法、单一字段逐个再次验证

复制代码
from Formtest import models
from django import forms
from django.forms import fields
from django.forms import widgets
from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
from django.core.validators import RegexValidator


class AjaxForm(forms.Form):
    user=fields.CharField(
        max_length=10,
        required=False,
        validators=[RegexValidator(r'^[a-z]+$', 'Enter a valid extension.', 'invalid')],
    )
    email=fields.EmailField()

    def clean_user(self):
        """
        Form中字段中定义的格式匹配完以后,执行此方法进行验证
        :return:
        """
        v = self.cleaned_data['user']
        if models.UserInfo.objects.filter(user=v).count():
            raise ValidationError('此用户名已经存在')
        return v

    def clean_email(self):
        """
        email验证过以后、能够自定义验证该邮箱是否被使用...
        :return: 
        """
        pass
复制代码

方式B

复制代码
from Formtest import models
from django import forms
from django.forms import fields
from django.forms import widgets
from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
from django.core.validators import RegexValidator


class AjaxForm(forms.Form):
    user = fields.CharField(
        max_length=10,
        required=False,
        validators=[RegexValidator(r'^[a-z]+$', 'Enter a valid extension.', 'invalid')],
    )
    email = fields.EmailField()

    def clean_user(self):
        """
        Form中字段中定义的格式匹配完以后,执行此方法进行验证
        :return:
        """
        v = self.cleaned_data['user']
        if models.UserInfo.objects.filter(user=v).count():
            raise ValidationError('此用户名已经存在')
        return v

    def clean_email(self):
        """
        email验证过以后、能够自定义验证该邮箱是否被使用...
        :return:
        """
        pass

    def clean(self):
        """
        在单字段自定义验证完成以后、也能够对总体进行一个验证
        :return: 
        """
        value_dict = self.cleaned_data
        user = value_dict.get('user')
        email = value_dict.get('email')
        if user == 'root' and email == 'root@163.com':
            raise ValidationError('身份验证信息验证失败')
        return value_dict


    # ps: _post_clean是clean验证完以后进一步验证操做、通常用不到
    #       全局错误信息地键是 __all__
复制代码
相关文章
相关标签/搜索