python-Django框架之【Form插件】

一、Form主要功能

  1、生成HTML标签

  2、验证用户数据(显示错误信息)

  3、生成HTML代码, Form提交保留上次提交数据

  4、初始化页面显示内容

二、使用流程

  1、创建Form类

from django import forms
class F1Form(forms.Form):

  2、创建字段(包含正则表达式)

from django.forms import fields

class F1Form(forms.Form):
    user = fields.CharField(
        min_length=6,
        max_length=12,
        required=True,
        error_messages={
            "min_length":"长度不够",
            "max_length":"长度太长",
            "required":"不能为空"}
    )

  事例:

 1 from django import forms
 2 from django.forms import fields
 3 
 4 class F1Form(forms.Form):
 5     user = fields.CharField(
 6         min_length=6,
 7         max_length=12,
 8         required=True,
 9         error_messages={
10             "min_length":"长度不够",
11             "max_length":"长度太长",
12             "required":"不能为空"}
13     )
14     pwd = fields.CharField(
15         min_length=6,
16         required=True,
17         error_messages={
18             "min_length": "长度不够",
19             "required": "不能为空"}
20     )
21     age = fields.IntegerField(
22         required=True,
23         error_messages={
24             "required": "不能为空"}
25     )
26     email = fields.EmailField(
27         required=True,
28         error_messages={
29             "required": "不能为空",
30             "invalid":"格式不正确"
31         }
32     )

  3、views中实例化Form类

    is_valid():是否验证成功

    cleaned_data:验证成功后要提交的数据(字典形式)

def index2(request):
    if request.method == "GET":
        obj = F1Form()    #用于生成HTML代码
        return render(request,"index2.html",{"obj":obj})
    elif request.method == "POST":
        obj = F1Form(request.POST)    #用于Form验证

        if obj.is_valid():    #判断是否验证成功
            return redirect("http://www.baidu.com")
        else:
            return render(request, "index2.html", {"obj": obj}):

  4、前端

    生成HTML代码

    obj.errors:验证失败后的错误信息

<form action="/index2.html" method="post" novalidate>

#也可以自己创建form表单元素,但是不会保留上一次输入的内容
{#    <p><input type="text" name="user">{{ obj.errors.user.0 }}</p>#}
{#    <p><input type="text" name="pwd">{{ obj.errors.pwd.0 }}</p>#}
{#    <p><input type="text" name="age">{{ obj.errors.age.0 }}</p>#}
{#    <p><input type="text" name="email">{{ obj.errors.email.0 }}</p>#}

#通过obj = F1Form()自动生成form表单元素
    <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
    <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
    <p>{{ obj.age }}{{ obj.errors.age.0 }}</p>
    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>

    <p><input type="submit" value="提交"></p>

</form>

  注意:如果不用obj = F1Form()生成html代码,则form表单中的元素的name属性值必须与Form类的字段名一致

  技巧:创建Form类时,字段名与models中的字段名(数据库字段名)一致,则验证成功后,直接提取obj.cleaned_data进行数据库记录的创建或修改(**obj.cleaned_data)。

 1     if request.method == "GET":
 2         obj = myforms.UserForm()
 3         return render(request,"add_user.html",{"obj":obj})
 4     elif request.method == "POST":
 5         obj = myforms.UserForm(request.POST)
 6         if obj.is_valid():
 7             models.UserInfo.objects.create(**obj.cleaned_data)
 8             return redirect("/users/")
 9         else:
10             return render(request,"add_user.html",{"obj":obj})
例

三、Django内置字段及属性

  每个字段都封装了一个正则表达式和默认的HTML插件

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

  1 Field
  2             required=True,               是否允许为空
  3             widget=None,                 HTML插件
  4             label=None,                  用于生成Label标签或显示内容
  5             initial=None,                初始值
  6             help_text='',                帮助信息(在标签旁边显示)
  7             error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
  8             show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
  9             validators=[],               自定义验证规则
 10             localize=False,              是否支持本地化
 11             disabled=False,              是否可以编辑
 12             label_suffix=None            Label内容后缀
 13 
 14 
 15         CharField(Field)
 16             max_length=None,             最大长度
 17             min_length=None,             最小长度
 18             strip=True                   是否移除用户输入空白
 19 
 20         IntegerField(Field)
 21             max_value=None,              最大值
 22             min_value=None,              最小值
 23         
 24         FloatField(IntegerField)
 25             ...
 26 
 27         DecimalField(IntegerField)
 28             max_value=None,              最大值
 29             min_value=None,              最小值
 30             max_digits=None,             总长度
 31             decimal_places=None,         小数位长度
 32 
 33         BaseTemporalField(Field)
 34             input_formats=None          时间格式化    
 35 
 36         DateField(BaseTemporalField)    格式:2015-09-01
 37         TimeField(BaseTemporalField)    格式:11:12
 38         DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
 39         
 40         DurationField(Field)            时间间隔:%d %H:%M:%S.%f
 41             ...
 42 
 43         RegexField(CharField)
 44             regex,                      自定制正则表达式
 45             max_length=None,            最大长度
 46             min_length=None,            最小长度
 47             error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
 48 
 49         EmailField(CharField)       
 50             ...
 51 
 52         FileField(Field)
 53             allow_empty_file=False     是否允许空文件
 54 
 55         ImageField(FileField)       
 56             ...
 57             注:需要PIL模块,pip3 install Pillow
 58             以上两个字典使用时,需要注意两点:
 59                 - form表单中 enctype="multipart/form-data"
 60                 - view函数中 obj = MyForm(request.POST, request.FILES)
 61 
 62         URLField(Field)
 63             ...
 64 
 65 
 66         BooleanField(Field)   
 67             ...
 68 
 69         NullBooleanField(BooleanField)
 70             ...
 71 
 72         ChoiceField(Field)
 73             ...
 74             choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
 75             required=True,             是否必填
 76             widget=None,               插件,默认select插件
 77             label=None,                Label内容
 78             initial=None,              初始值
 79             help_text='',              帮助提示
 80 
 81         
 82         ModelChoiceField(ChoiceField)
 83             ...                        django.forms.models.ModelChoiceField
 84             queryset,                  # 查询数据库中的数据
 85             empty_label="---------",   # 默认空显示内容
 86             to_field_name=None,        # HTML中value的值对应的字段
 87             limit_choices_to=None      # ModelForm中对queryset二次筛选
 88             
 89         ModelMultipleChoiceField(ModelChoiceField)
 90             ...                        django.forms.models.ModelMultipleChoiceField
 91 
 92 
 93             
 94         TypedChoiceField(ChoiceField)
 95             coerce = lambda val: val   对选中的值进行一次转换
 96             empty_value= ''            空值的默认值
 97 
 98         MultipleChoiceField(ChoiceField)
 99             ...
100 
101         TypedMultipleChoiceField(MultipleChoiceField)
102             coerce = lambda val: val   对选中的每一个值进行一次转换
103             empty_value= ''            空值的默认值
104         
105         ComboField(Field)
106             fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
107                                        fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
108         
109         MultiValueField(Field)
110             PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
111 
112         SplitDateTimeField(MultiValueField) 
113             input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
114             input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
115 
116         FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
117             path,                      文件夹路径
118             match=None,                正则匹配
119             recursive=False,           递归下面的文件夹
120             allow_files=True,          允许文件
121             allow_folders=False,       允许文件夹
122             required=True, 
123             widget=None, 
124             label=None,
125             initial=None, 
126             help_text=''
127         
128         GenericIPAddressField
129             protocol='both',           both,ipv4,ipv6支持的IP格式
130             unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
131 
132         SlugField(CharField)           数字,字母,下划线,减号(连字符)
133             ...
134 
135         UUIDField(CharField)           uuid类型
136             ...
137         
138         
139 
140 注:UUID是根据MAC以及当前时间等创建的不重复的随机字符串
 1    >>> import uuid
 2 
 3     # make a UUID based on the host ID and current time
 4     >>> uuid.uuid1()    # doctest: +SKIP
 5     UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
 6 
 7     # make a UUID using an MD5 hash of a namespace UUID and a name
 8     >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
 9     UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
10 
11     # make a random UUID
12     >>> uuid.uuid4()    # doctest: +SKIP
13     UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
14 
15     # make a UUID using a SHA-1 hash of a namespace UUID and a name
16     >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
17     UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
18 
19     # make a UUID from a string of hex digits (braces and hyphens ignored)
20     >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
21 
22     # convert a UUID to a string of hex digits in standard form
23     >>> str(x)
24     '00010203-0405-0607-0809-0a0b0c0d0e0f'
25 
26     # get the raw 16 bytes of the UUID
27     >>> x.bytes
28     b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
29 
30     # make a UUID from a 16-byte string
31     >>> uuid.UUID(bytes=x.bytes)
32     UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
UUID

四、Django内置插件

    插件用于自动生成HTML标签

TextInput(Input)
NumberInput(TextInput)
EmailInput(TextInput)
URLInput(TextInput)
PasswordInput(TextInput)
HiddenInput(TextInput)
Textarea(Widget)
DateInput(DateTimeBaseInput)
DateTimeInput(DateTimeBaseInput)
TimeInput(DateTimeBaseInput)
CheckboxInput
Select
NullBooleanSelect
SelectMultiple
RadioSelect
CheckboxSelectMultiple
FileInput
ClearableFileInput
MultipleHiddenInput
SplitDateTimeWidget
SplitHiddenDateTimeWidget
SelectDateWidget

五、常用选择插件

  导入:from django.forms import widgets

# 单radio,值为字符串
    # user = fields.CharField(
    #     initial=2,
    #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
    # )

    # 单radio,值为字符串
    # user = fields.ChoiceField(
    #     choices=((1, '上海'), (2, '北京'),),
    #     initial=2,
    #     widget=widgets.RadioSelect
    # )

    # 单select,值为字符串
    # user = fields.CharField(
    #     initial=2,
    #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
    # )

    # 单select,值为字符串
    # user = fields.ChoiceField(
    #     choices=((1, '上海'), (2, '北京'),),
    #     initial=2,
    #     widget=widgets.Select
    # )

    # 多选select,值为列表
    # user = fields.MultipleChoiceField(
    #     choices=((1,'上海'),(2,'北京'),),
    #     initial=[1,],
    #     widget=widgets.SelectMultiple
    # )


    # 单checkbox
    # user = fields.CharField(
    #     widget=widgets.CheckboxInput()
    # )


    # 多选checkbox,值为列表
    # user = fields.MultipleChoiceField(
    #     initial=[2, ],
    #     choices=((1, '上海'), (2, '北京'),),
    #     widget=widgets.CheckboxSelectMultiple
    # )

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

  方式一:推荐使用

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

  方式二:使用django提供的ModelChoiceField和ModelMultipleChoiceField字段来实现,需要models中类中包含__str__()方法配合,如果多个select,则无法实现,解耦性差。

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

六、自定义验证规则

七、初始化数据

posted @ 2017-03-17 09:20  黑龙orz  阅读(179)  评论(0)    收藏  举报