zoukankan      html  css  js  c++  java
  • WEB框架Django进阶----form验证

    form组件

    form验证

    以前我们写form表单验证是这样的:

    views.py

     1 def login(request):
     2     # f = open("templates/login.html","r",encoding="utf-8")
     3     # date = f.read()
     4     # f.close()
     5 
     6     error_msg = " "
     7     if request.method == "POST":
     8         user = request.POST.get("user",None)
     9         pwd = request.POST.get("pwd",None)
    10 
    11         if user=="root" and pwd=="123":
    12             return redirect("http://www.baidu.com")
    13         else:
    14             error_msg = "用户名密码错误"
    15 
    16     return render(request,"login.html",{"error_msg":error_msg})
    View Code

    login.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <link rel="stylesheet" href="/static/commons.css" />
     7     <style>
     8         label{
     9             width: 80px;
    10             text-align: right;
    11             display: inline-block;
    12         }
    13     </style>
    14 </head>
    15 <body>
    16         <form action="/login/" method="post">
    17         <p>
    18             <label for="username">用户名:</label>
    19             <input id="username" name="user" type="text" />
    20         </p>
    21         <p>
    22             <label for="password">密码:</label>
    23             <input id="password" name="pwd" type="text" />
    24             <input type="submit" value="提交" />
    25             <span style="color: red">{{ error_msg }}</span>
    26         </p>
    27     </form>
    28     <script src="/static/jquery-1.12.4.js"></script>
    29 </body>
    30 </html>
    View Code

    这样是可以的,但是不能细化每行的错误提示,其实在django中django自带了form的验证

    是这样的

    views.py

     1 from django import forms
     2 class FM(forms.Form):
     3     user = forms.CharField(error_messages={"required":"用户名不能为空"})
     4     pwd = forms.CharField(
     5         max_length=12,
     6         min_length=6,
     7         error_messages={"required":"密码不能为空","max_length":"密码长度不能超过12","min_length":"密码长度不能小于6"}
     8     )
     9     email = forms.EmailField(error_messages={"required":"邮箱不能为空","invalid":"邮箱格式不正确"})
    10 
    11 def fm(request):
    12     if request.method == "GET":
    13         return render(request,"fm.html")
    14     elif request.method == "POST":
    15         obj = FM(request.POST)
    16         r1 = obj.is_valid()
    17         # print(r1)
    18         if r1:
    19             print(obj.cleaned_data)
    20         else:
    21             print(obj.errors)
    22             return render(request, "fm.html",{"obj":obj})

    fm.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8     <form action="/fm/" method="post">
     9         {% csrf_token %}
    10         <p><input type="text" name="user" />{{ obj.errors.user.0 }}</p>
    11         <p><input type="text" name="pwd" />{{ obj.errors.pwd.0 }}</p>
    12         <p><input type="text" name="email" />{{ obj.errors.email.0 }}</p>
    13         <p><input type="submit" value="提交" /></p>
    14 
    15     </form>
    16 </body>
    17 </html>

    显示效果:

    但是还存在一个问题,你看,一点提交,数据都跑哪里了, 填写的数据不见了,怎么办呢?那要是我们想保留上一次操作的数据?

    可以这样搞一下,

    django中的form还可以生成<input>标签的

    views.py

    1 def fm(request):
    2     if request.method == "GET":
    3         obj = FM()
    4         return render(request,"fm.html",{"obj":obj})

    fm.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8     <form action="/fm/" method="post">
     9         {% csrf_token %}
    10         <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>
    11         <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>
    12         <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>
    13         <p><input type="submit" value="提交" /></p>
    14 
    15     </form>
    16 </body>
    17 </html>

    显示效果:

     那如果提交是正确的数据呢?返回到后端显示的是一个字典格式的

    那么这样写就可以在数据库中添加一个用户,完成注册了

     1 from app01 import models
     2 def fm(request):
     3     if request.method == "GET":
     4         obj = FM()
     5         return render(request,"fm.html",{"obj":obj})
     6     elif request.method == "POST":
     7         obj = FM(request.POST)
     8         r1 = obj.is_valid()
     9         # print(r1)
    10         if r1:
    11             #print(obj.cleaned_data)
    12             models.UserInfo.objects.create(**obj.cleaned_data)   #完成注册添加进数据库

    在html中还 可以在简化,看下面

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8     <form action="/fm/" method="post">
     9         {% csrf_token %}
    10 {#        <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>#}
    11 {#        <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>#}
    12 {#        <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>#}
    13         {{ obj.as_p }}
    14 
    15         {{ obj.as_ul }}
    16 
    17         <table>{{ obj.as_table }}</table>
    18         
    19         <p><input type="submit" value="提交" /></p>
    20 
    21     </form>
    22 </body>
    23 </html>

    显示效果:

    但是不建议这样做,这样做不能针对每一个自定制的标签做处理。

    form字段,用于对用户请求数据的验证

    1 from django import forms
    2 from django.forms import fields #字段
    3 from django.forms import widgets #插件
    4 class FM(forms.Form):
    5     user = fields.CharField(
    6         error_messages={"required":"用户名不能为空"},
    7         widget=widgets.CheckboxInput(attrs={"class":"c1",})
    8     )

     django的内置字段

      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     ...
    View Code

    注: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'x00x01x02x03x04x05x06x07x08	
    x0bx0c
    x0ex0f'
    29 
    30     # make a UUID from a 16-byte string
    31     >>> uuid.UUID(bytes=x.bytes)
    32     UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
    View Code

    form插件,用于生成HTML

     内置插件

     1 TextInput(Input)
     2 NumberInput(TextInput)
     3 EmailInput(TextInput)
     4 URLInput(TextInput)
     5 PasswordInput(TextInput)
     6 HiddenInput(TextInput)
     7 Textarea(Widget)
     8 DateInput(DateTimeBaseInput)
     9 DateTimeInput(DateTimeBaseInput)
    10 TimeInput(DateTimeBaseInput)
    11 CheckboxInput
    12 Select
    13 NullBooleanSelect
    14 SelectMultiple
    15 RadioSelect
    16 CheckboxSelectMultiple
    17 FileInput
    18 ClearableFileInput
    19 MultipleHiddenInput
    20 SplitDateTimeWidget
    21 SplitHiddenDateTimeWidget
    22 SelectDateWidget
    View Code

    常用选择插件

     1 # 单radio,值为字符串
     2 # user = fields.CharField(
     3 #     initial=2,
     4 #     widget=widgets.RadioSelect(choices=((1,'上海'),(2,'北京'),))
     5 # )
     6  
     7 # 单radio,值为字符串
     8 # user = fields.ChoiceField(
     9 #     choices=((1, '上海'), (2, '北京'),),
    10 #     initial=2,
    11 #     widget=widgets.RadioSelect
    12 # )
    13  
    14 # 单select,值为字符串
    15 # user = fields.CharField(
    16 #     initial=2,
    17 #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
    18 # )
    19  
    20 # 单select,值为字符串
    21 # user = fields.ChoiceField(
    22 #     choices=((1, '上海'), (2, '北京'),),
    23 #     initial=2,
    24 #     widget=widgets.Select
    25 # )
    26  
    27 # 多选select,值为列表
    28 # user = fields.MultipleChoiceField(
    29 #     choices=((1,'上海'),(2,'北京'),),
    30 #     initial=[1,],
    31 #     widget=widgets.SelectMultiple
    32 # )
    33  
    34  
    35 # 单checkbox
    36 # user = fields.CharField(
    37 #     widget=widgets.CheckboxInput()
    38 # )
    39  
    40  
    41 # 多选checkbox,值为列表
    42 # user = fields.MultipleChoiceField(
    43 #     initial=[2, ],
    44 #     choices=((1, '上海'), (2, '北京'),),
    45 #     widget=widgets.CheckboxSelectMultiple
    46 # )
    View Code

    初始化数据:

     1 from app01 import models
     2 def fm(request):
     3     if request.method == "GET":
     4         #从数据库中把数据拿到
     5         dic={
     6             "user":"uytr",
     7             "pwd":"123dfas",
     8             "email":"abcd@sina.com"
     9         }
    10         obj = FM(initial=dic)
    11         return render(request,"fm.html",{"obj":obj})

    https://www.cnblogs.com/wupeiqi/articles/6144178.html

  • 相关阅读:
    课堂派题库格式转换程序
    操作系统——进程的状态与转换
    android 通用 Intent
    android上使用蓝牙设备进行语音输入
    讯飞语音听写中数字规整问题
    【Android】隐藏底部虚拟按键
    AudioEffect中文API
    为什么要在onNewIntent的时候要显示的去调用setIntent
    android蓝牙耳机下的语音(输入/识别)及按键监听
    Android如何监听蓝牙耳机的按键事件
  • 原文地址:https://www.cnblogs.com/garrett0220/p/9081764.html
Copyright © 2011-2022 走看看