zoukankan      html  css  js  c++  java
  • Day22-Django之Form组件验证

    1. Django里面的Form专门用来做验证。

    用Form创建一个类,把用户发来的数据放到request.POST里面发给这个类,这个类会帮忙做验证。

    返回3个结果:是否验证成功了,所有的正确信息,所有的错误信息。

    name值必须与FM类里面的对应才能拿到数据。

    2. 定义了一个类,它继承了forms.Form。我想验证哪个,就把哪个写到这个类里。

    from django import forms
    class FM(forms.Form):
        user=forms.CharField()
        pwd=forms.CharField()
        email=forms.EmailField()
    

     

    3.views.py,

    r1=obj.is_valid()就是做验证,如果验证通过,则返回True; 如果验证失败,则返回False.

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField()
        pwd=forms.CharField()
        email=forms.EmailField()
    
    def fm(request): 
        if request.method=='GET':
            return render(request,'fm.html')
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)  #创建对象,把request.POST里面的数据都传过去。
            r1=obj.is_valid()
            print(r1)
            return redirect('/fm/')
    

     

    4. 完善程序:通过obj.is_valid,obj.cleaned_data, obj.errors 三种方法得到了所有验证结果。

    views.py

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField()
        pwd=forms.CharField()
        email=forms.EmailField()
    
    def fm(request):
        if request.method=='GET':
            return render(request,'fm.html')
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                print(obj.cleaned_data) #输出所有的正确信息
            else:
                print(obj.errors.as_json()) #输出所有的错误信息。本来是字符串,通过as_json()方法可以得到字典类型的输出。
            return redirect('/fm/')
    

     

    5. 通过传参数,也可以定制想要显示的错误信息。把错误信息显示为中文。把code下所对应的值替换掉。

    required 替换为:不能为空。

    invalid 替换为 格式错误。

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField(error_messages={'required':'用户名不能为空'})
        pwd=forms.CharField()
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    def fm(request):
        if request.method=='GET':
            return render(request,'fm.html')
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                print(obj.cleaned_data)
            else:
                print(obj.errors)
            return redirect('/fm/')
    

     

    6. 完善密码部分的验证:最大长度-最小长度

    views.py

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField(error_messages={'required':'用户名不能为空'})
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    def fm(request):
        if request.method=='GET':
            return render(request,'fm.html')
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                print(obj.cleaned_data)
            else:
                print(obj.errors)
            return redirect('/fm/')
    

     效果:

    7. 把错误信息obj.errors传到前端,

    views.py

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField(error_messages={'required':'用户名不能为空'})
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    def fm(request):
        if request.method=='GET':
            return render(request,'fm.html')
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                print(obj.cleaned_data)
            else:
                #ErrorDict, obj.errors继承了Dict,所以取数据的时候不能通过点,应该通过['user']
                print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

     obj.errors 里面包含了所有的错误信息。 {{obj.errors.user.0}} 取user下面的第一个错误信息。

    fm.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/fm/" method="POST">
            {% csrf_token %}
            <p><input type="text" name="user" placeholder="username"/>{{obj.errors.user.0}}</p>
            <p><input type="password" name="pwd" placeholder="password"/>{{obj.errors.pwd.0}}</p>
            <p><input type="text" name="email" placeholder="email"/>{{obj.errors.email.0}}</p>
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    

     效果:

    8. 到目前为止,一点提交,错误信息是显示出来了,可是用户输入的值也被刷新,找不到了。

    obj可以自动帮我们生成各种标签。

    views.py

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField(error_messages={'required':'用户名不能为空'})
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    def fm(request):
        if request.method=='GET':
            obj=FM() #当用GET方式请求时,也需要创建一个对象。不需要传参数,因为在前端不需要看到任何数据。
            return render(request,'fm.html',{'obj':obj})
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                print(obj.cleaned_data)
            else:
                #ErrorDict继承了Dict
                #print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

     fm.html: <p>{{obj.user}}{{obj.errors.user.0}}</p> ,写obj.user, 自动生成input标签,

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/fm/" method="POST">
            {% csrf_token %}
            <p>{{obj.user}}{{obj.errors.user.0}}</p>
            <p>{{obj.pwd}}{{obj.errors.pwd.0}}</p>
            <p>{{obj.email}}{{obj.errors.email.0}}</p>
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    

     效果:自动生成了input标签。高级浏览器生成的标签比较多,比较全。

    而且如果输入不合法的话,显示错误信息的同时,也会保留用户当前的输入。

    obj.cleaned_data 里面存放的是所有正确的值,通过验证的值。是一个字典,所以可以通过

    models.UserInfo.objects.create(**obj.cleaned_data) 生成表中数据。

    通过form做了2件事,

    1-做用户请求的验证;2-帮用户在页面上生成HTML标签;生成HTML标签的同时,替用户保留了上次提交的数据。

    9.还有更简单的方法,

    fm.html修改如下: obj.as_p 意思是p标签。

     fm.html修改如下: obj.as_ur 意思是ur标签

    fm.html修改如下: obj.as_table 意思是table标签 ; 注意用table的时候,要在外面加1个table标签。

    上述3种,生成方便,但是定制性差。所以还是建议用下面的

    程序粘贴:

    models.py

    from django.db import models
    
    # Create your models here.
    class UserInfo(models.Model):
        user=models.CharField(max_length=32)
    

     fm.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/fm/" method="POST">
            {% csrf_token %}
            <p>{{obj.user}}{{obj.errors.user.0}}</p>
            <p>{{obj.pwd}}{{obj.errors.pwd.0}}</p>
            <p>{{obj.email}}{{obj.errors.email.0}}</p>
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    

     views.py

    #####################From########################
    from django import forms
    class FM(forms.Form):
        user=forms.CharField(error_messages={'required':'用户名不能为空'})
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    from app01 import models
    def fm(request):
        if request.method=='GET':
            obj=FM()
            return render(request,'fm.html',{'obj':obj})
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                models.UserInfo.objects.create(**obj.cleaned_data)
            else:
                #ErrorDict继承了Dict
                #print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

     urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/$', views.login),
        url(r'^index/$', views.index),
        url(r'^logout/$', views.logout),
        url(r'^test/(d+)$', views.test),
        url(r'^cache/$', views.cache),
        url(r'^signal/$', views.signal),
        url(r'^fm/$', views.fm),
    ]
    

    10. 那么input框的样式怎么设置呢?

    CharField,emailField 这些是做验证功能的。CharField里面有个type=text的默认插件。

    生成HTML的功能在另外一个插件中完成,widget就是插件的意思。

    widget=widgets.Textarea(attrs={'class':'c1'}), widgets.Textarea:定制插件。 attrs:定义样式。
    from django.forms import widgets
    #####################From########################
    from django import forms
    from django.forms import widgets
    class FM(forms.Form):
        #字段本身只做验证,CharField内部隐含了一个插件。
        user=forms.CharField(
            error_messages={'required':'用户名不能为空'},
            widget=widgets.Textarea()
    
        )
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    from app01 import models
    def fm(request):
        if request.method=='GET':
            obj=FM()
            return render(request,'fm.html',{'obj':obj})
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                models.UserInfo.objects.create(**obj.cleaned_data)
            else:
                #ErrorDict继承了Dict
                #print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

     效果:

    11. 给Textarea加上样式

    #####################From########################
    from django import forms
    from django.forms import widgets
    class FM(forms.Form):
        #字段本身只做验证,CharField内部隐含了一个插件。
        user=forms.CharField(
            error_messages={'required':'用户名不能为空'},
            widget=widgets.Textarea(attrs={'class':'c1'})
    
        )
        pwd=forms.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'}
        )
        email=forms.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
    from app01 import models
    def fm(request):
        if request.method=='GET':
            obj=FM()
            return render(request,'fm.html',{'obj':obj})
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                models.UserInfo.objects.create(**obj.cleaned_data)
            else:
                #ErrorDict继承了Dict
                #print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

    可以定义字段,定义在页面上显示的是什么插件,还可以自定义样式。

    from django.forms import fields  所有字段都在这里面放着呢。
    以后就不用写成forms.CharField的样子的,只需要写成fields.CharField的样子就可以了。
    from django.forms import widgets  所有插件都在这里面放着呢。
    widgets插件里面都有些什么呢:input,select,checkbox,radio等都有。
    通过is_valid(),obj.cleaned_data(),obj.errors()拿到所有的返回值,在每个field字段里面做验证,字段里面包含了插件,
    是专门用来生成HTML页面的

    12,widget=widgets.PasswordInput(attrs={'class':'c2'}) 专门针对password的插件。attrs是定义样式。
    效果:



    13,其它字段的介绍,专门用来做验证的。

    label标签和默认值示例



    FileField(Field)示例:真正上传的时候,以前form表单里面需要加一句特殊的设置,否则上传不成功。
    在此处上传的文件也保存在cleaned_data里面,cleaned_data里面保存的时候是字典的格式。在此处拿到文件名(key)以后,也需要执行chunks才能成功。


    FilePathField(ChoiceField)示例:把一个文件夹下的所有文件都显示出来了。



    ChoiceField(Field)示例:
    city=fields.MultipleChoiceField




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

    
    

    14.1、Django内置字段如下:

            Field #是下面所有函数的基类
                required=True,               是否允许为空
                widget=None,                 HTML插件
                label=None,                  用于生成Label标签或显示内容
                initial=None,                初始值
                help_text='',                帮助信息(在标签旁边显示)
                error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
                show_hidden_initial=False,   是否在当前插件后面再加一个隐藏的且具有默认值的插件(可用于检验两次输入是否一直)
                validators=[],               自定义验证规则,自定义正则表达式进行验证。
                localize=False,              是否支持本地化
                disabled=False,              是否可以编辑
                label_suffix=None            Label内容后缀
    
    
            CharField(Field) #继承了Field,Field里面的参数它都可以用。
                max_length=None,             最大长度
                min_length=None,             最小长度
                strip=True                   是否移除用户输入空白

            IntegerField(Field)
                max_value=None,              最大值
                min_value=None,              最小值
           
            FloatField(IntegerField)
                ...

            DecimalField(IntegerField)
                max_value=None,              最大值
                min_value=None,              最小值
                max_digits=None,             总长度
                decimal_places=None,         小数位长度

            BaseTemporalField(Field)
                input_formats=None          时间格式化   

            DateField(BaseTemporalField)    格式:2015-09-01
            TimeField(BaseTemporalField)    格式:11:12
            DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
           
            DurationField(Field)            时间间隔:%d %H:%M:%S.%f
                ...
    RegexField(CharField)
                regex,                      自定制正则表达式
                max_length=None,            最大长度
                min_length=None,            最小长度
                error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}

            EmailField(CharField)      
                ...

            FileField(Field) 上传文件用的
                allow_empty_file=False     是否允许空文件

            ImageField(FileField)      
                ...
                注:需要PIL模块,pip3 install Pillow
                以上两个字典使用时,需要注意两点:
                    - form表单中 enctype="multipart/form-data"
                    - view函数中 obj = MyForm(request.POST, request.FILES)

            URLField(Field)
                ...
            BooleanField(Field)  
                ...

            NullBooleanField(BooleanField)
                ...

            ChoiceField(Field)
                ...
                choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
                required=True,             是否必填
                widget=None,               插件,默认select插件
                label=None,                Label内容
                initial=None,              初始值
                help_text='',              帮助提示

           
            ModelChoiceField(ChoiceField)
                ...                        django.forms.models.ModelChoiceField
                queryset,                  # 查询数据库中的数据
                empty_label="---------",   # 默认空显示内容
                to_field_name=None,        # HTML中value的值对应的字段
                limit_choices_to=None      # ModelForm中对queryset二次筛选
         ModelMultipleChoiceField(ModelChoiceField)
                ...                        django.forms.models.ModelMultipleChoiceField


               
            TypedChoiceField(ChoiceField)
                coerce = lambda val: val   对选中的值进行一次转换
                empty_value= ''            空值的默认值

            MultipleChoiceField(ChoiceField)
                ...

            TypedMultipleChoiceField(MultipleChoiceField)
                coerce = lambda val: val   对选中的每一个值进行一次转换
                empty_value= ''            空值的默认值
           
            ComboField(Field)
                fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                                           fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
           
            MultiValueField(Field)         PS: 抽象类,抽象类是只能被继承。子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用


           SplitDateTimeField(MultiValueField) 能实现1个字段对应多个input框
                input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
                input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']

            FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹
                required=True,
                widget=None,
                label=None,
                initial=None,
                help_text=''
           
            GenericIPAddressField
                protocol='both',           both,ipv4,ipv6支持的IP格式
                unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
            SlugField(CharField)           数字,字母,下划线,减号(连字符)
                ...

            UUIDField(CharField)           uuid类型
                ...
           




    14.2 Django常用插件:

    >>> import uuid
    
        # make a UUID based on the host ID and current time
        >>> uuid.uuid1()    # doctest: +SKIP
        UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
    
        # make a UUID using an MD5 hash of a namespace UUID and a name
        >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
        UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
    
        # make a random UUID
        >>> uuid.uuid4()    # doctest: +SKIP
        UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
    
        # make a UUID using a SHA-1 hash of a namespace UUID and a name
        >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
        UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
    
        # make a UUID from a string of hex digits (braces and hyphens ignored)
        >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
    
        # convert a UUID to a string of hex digits in standard form
        >>> str(x)
        '00010203-0405-0607-0809-0a0b0c0d0e0f'
    
        # get the raw 16 bytes of the UUID
        >>> x.bytes
        b'x00x01x02x03x04x05x06x07x08	
    x0bx0c
    x0ex0f'
    
        # make a UUID from a 16-byte string
        >>> uuid.UUID(bytes=x.bytes)
        UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
    
     
    常用选择插件
    # 单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,值为字符串,写法1
    
    # user = fields.CharField(
    
    #     initial=2,
    
    #     widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))
    
    # )
    
     
    
    # 单select,值为字符串,写法2
    
    # 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
    
    # )
    
    
    

     笔记


    15. 初始化操作



    程序粘贴:

    views.py
    #####################From########################
    from django import forms
    from django.forms import widgets
    from django.forms import fields  #字段都在fields中
    class FM(forms.Form):
        #字段本身只做验证,CharField内部隐含了一个插件。
        user=fields.CharField(
            error_messages={'required':'用户名不能为空'},
            widget=widgets.Textarea(attrs={'class':'c1'}),
            label="用户名",
            #initial='root',
        )
        pwd=fields.CharField(
            max_length=12,
            min_length=6,
            error_messages={'required': '密码不能为空','min_length':'密码长度不能小于6','max_length':'密码长度不能大于12'},
            widget=widgets.PasswordInput(attrs={'class':'c2'})
        )
        email=fields.EmailField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
    
        f=fields.FileField()
        #p=fields.FilePathField(path='app01')
        city1=fields.ChoiceField(
            choices=[(0,'上海'),(1,'广州'),(2,'东莞'),]
        )
        city2=fields.MultipleChoiceField(
            choices=[(0,'上海'),(1,'广州'),(2,'东莞'),]
        )
    
    from app01 import models
    def fm(request):
        if request.method=='GET':
            #从数据库中把数据都获取到
            dic={
                'user':'user1',
                'pwd':'123123',
                'email':'sdfsd',
                'city1':1,
                'city2':[1,2]
            }
            obj=FM(initial=dic)
            return render(request,'fm.html',{'obj':obj})
        elif request.method=='POST':
            #获取用户提交的所有数据,对每条数据进行验证,#
            # 成功之后,获取所有正确的信息;若失败,显示错误信息
            obj=FM(request.POST)
            r1=obj.is_valid()
            if r1:
                models.UserInfo.objects.create(**obj.cleaned_data)
            else:
                #ErrorDict继承了Dict
                #print(obj.errors['user'])
                return render(request,'fm.html',{'obj':obj})
    

    fm.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/fm/" method="POST">
            {% csrf_token %}
            <p>{{obj.user.label}}{{obj.user}}{{obj.errors.user.0}}</p>
            <p>{{obj.pwd}}{{obj.errors.pwd.0}}</p>
            <p>{{obj.email}}{{obj.errors.email.0}}</p>
            <p>{{obj.f}}{{obj.errors.f.0}}</p>
            {{obj.p}}
            {{obj.city1}}
            {{obj.city2}}
            <input type="submit" value="提交"/>
        </form>
    </body>
    </html>
    
    
    
    
    
    
    





    参考老师博客:http://www.cnblogs.com/wupeiqi/articles/6144178.html














  • 相关阅读:
    原型污染
    C#之抛异常
    为什么['1', '7', '11'].map(parseInt) returns [1, NaN, 3]?
    Linux
    Linux
    Linux
    Linux
    Linux
    Linux
    其他
  • 原文地址:https://www.cnblogs.com/momo8238/p/7729145.html
Copyright © 2011-2022 走看看