forms_formselects 监听变化 - CSDN
精华内容
参与话题
  • forms组件

    2019-03-13 11:52:00
    就是将form表单中的值在post请求发送到服务端时,服务端利用forms组件去检验是否符合规则 form表单中的name属性值要和自定义forms组件的字段一致 <h3>简单form</h3&...

    校验功能

    • 就是将form表单中的值在post请求发送到服务端时,服务端利用forms组件去检验是否符合规则
    • form表单中的name属性值要和自定义forms组件的字段一致
               <h3>简单form</h3>
    
    
                <form action="" method="post" >
                    {% csrf_token %}
                    <p>用户名<input type="text" name="name"></p>
                    <p>密码 <input type="text" name="pwd"></p>
                    <p>确认密码 <input type="text" name="r_pwd"></p>
                    <p>邮箱  <input type="text" name="email"></p>
                    <p>手机号 <input type="text" name="tel"></p>
                    <input type="submit">
    
                </form>
    
    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    
    """
    1、引入forms组件 
        from django import forms
    2、自定义类,继承组件,并指定需要验证的字段和规则,规则默认非空
         class UserForm(forms.Form):
            name=forms.CharField(min_length=4)
            email=forms.EmailField()
    3、实例化对象并引用父类方法 is_valid(),验证字段。
        form=UserForm({"name":"yu","email":"123@qq.com"})
        print(form.is_valid()) # 返回布尔值
    """
    
    
    from django import forms
    
    class UserForm(forms.Form):
        name = forms.CharField(min_length=4)
        email = forms.EmailField()
    
    def reg(request):
        if request.method == "POST":
            print(request.POST)
    
            # form表单的name属性值应该与forms组件字段名称一致
            form=UserForm({"name":"xiaoming","email":"123@qq.com"})
            print(form.is_valid())  # 返回布尔值
    
            # 如果定义字段都匹配成功了,其他的不关心,是true
            form=UserForm({"name":"xiaoming","email":"123@qq.com","xxxx":"yyy"})
            print(form.is_valid())  # 返回布尔值
    
            if form.is_valid():
                print(form.cleaned_data)
                # 验证正常,cleaned_data可以拿到定义字段的字典形式的值{"name":"yuan","email":"123@qq.com"}
                # 没有多存的"xxxx":"yyy"
    
            else:
                # 有正确的有错误的分别放置:
                form = UserForm({"name": "xi", "email": "123@qq.com", "xxxx": "yyy"})
                print(form.cleaned_data)  # {"email":"123@qq.com"}
                print(form.errors)  # {"name":["对应错误提示信息"]}
    
                # print(type(form.errors))  # ErrorDict
                # print(form.errors.get("name"))
                # print(type(form.errors.get("name")))    # ErrorList
                # print(form.errors.get("name")[0])  # 拿到错误信息
    
    
            # 实际中我们需要验证的是post请求中的数据
            # form表单中name属性和自定义要验证的字段
    
            form = UserForm(request.POST)
    
    
            return HttpResponse('ok')
    
        return render(request, "reg.html")
    
    

    标签渲染功能

    上述html文件中form表单是自己写的,要保证字段一致。
    forms组件还可以自动渲染标签

    方式1:

    class UserForm(forms.Form):
        name = forms.CharField(min_length=4)
        email = forms.EmailField()
    
    form=UserForm()  # 第一次get请求时生成一个空对象传给html
        return render(request,"reg.html",locals())
    
                 <form action="" method="post">
                    {% csrf_token %}
                    <p>用户名
                       {{ form.name }}
                  </p>
                    <p>密码 {{ form.pwd }}</p>
                    <input type="submit">
                </form>
    
    

    方式二:

    循环form,起别名

    class UserForm(forms.Form):
        name=forms.CharField(min_length=4,label="用户名")
        pwd=forms.CharField(min_length=4,label="密码",)
        r_pwd=forms.CharField(min_length=4,label="确认密码")
        email=forms.EmailField(label="邮箱")
        tel=forms.CharField(label="手机号")
    
    form=UserForm()  # 第一次get请求时生成一个空对象传给html
        return render(request,"reg.html",locals())
    
    
                 <form action="" method="post">
                    {% csrf_token %}
                  {{% for field in form %}}
    
                     <p>
                         <label for="">{{ field.label }}</label>
                         {# 根据字段渲染input标签#}
                         {{ field }}
                     </p>
                    <input type="submit">
    
                </form>
    
    

    方式三、
    在方式二的基础上调用 form.as_p,不建议用,样式没法更改。

                <h3>forms组件渲染方式3</h3>
    
                <form action="" method="post">
                     {% csrf_token %}
    
                     {{ form.as_p }}
    
                     <input type="submit">
                </form>
    
    

    渲染错误信息

    • 模板里在每个输入行添加span标签,然后利用 form.pwd.errors.0 获取错误信息
    • 校验不全对时重返界面,return render(request, "reg.html", locals())同时保留数据。
    def reg(request):
        if request.method == "POST":
            form = UserForm(request.POST)
            if form.is_valid():
                print(form.cleaned_data)  # 所有干净的字段以及对应的值
            else:
                print(form.cleaned_data)  #
                print(form.errors)  # ErrorDict : {"校验错误的字段":["错误信息",]}
                print(form.errors.get("name"))  # ErrorList ["错误信息",]
                return render(request, "reg.html", locals())
    
        form=UserForm()  # get传给模板,模板自动渲染
        return render(request, "reg.html", locals())
    
     <form action="" method="post" novalidate>
    
                    {% csrf_token %}
                    <p>{{ form.name.label }}
                        {{ form.name }} <span class="pull-right error">{{ form.name.errors.0 }}</span>
                    </p>
                    <p>{{ form.pwd.label }}
                        {{ form.pwd }} <span class="pull-right error">{{ form.pwd.errors.0 }}</span>
                    </p>
                    <p>确认密码
                        {{ form.r_pwd }} <span class="pull-right error">{{ form.r_pwd.errors.0 }}</span><span class="pull-right error">{{ errors.0 }}</span>
                    </p>
                    <p>邮箱 {{ form.email }} <span class="pull-right error">{{ form.email.errors.0 }}</span></p>
                    <p>手机号 {{ form.tel }} <span class="pull-right error">{{ form.tel.errors.0 }}</span></p>
                    <input type="submit">
    
                </form>
    

    模板另外一种渲染方式提示错误信息:

    <form action="" method="post" novalidate>
        {% csrf_token %}
    
        {% for field in form %}
            <div>
                <label for="">{{ field.label }}</label>
                {{ field }} <span class="pull-right" style="color: red">{{ field.errors.0 }}</span>
            </div>
        {% endfor %}
        <input type="submit" class="btn btn-default">
    
    </form>
    

    改进参数

    
    """
    widget 定义标签input类型
    attrs={"class":"form-control"}定义标签属性,属性名和值
    :widget=widgets.PasswordInput(attrs={"class":"form-control"})
    自定义错误提示信息:error_messages={"required":"该字段不能为空","invalid":"格式错误"}
    
    """
    
    class UserForm(forms.Form):
        name=forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
                             widget=widgets.TextInput(attrs={"class":"form-control"})
                             )
        pwd=forms.CharField(min_length=4,label="密码",
                            widget=widgets.PasswordInput(attrs={"class":"form-control"})
                            )
        r_pwd=forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        email=forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        tel=forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
    

    局部钩子,再次校验

    单独摘出来定义文件,views文件引入

    from django import forms
    
    from django.forms import widgets
    from app01.models import UserInfo
    
    from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
    
    """
    1、引入错误类型:from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
    (源码:如果定义类有此方法,执行方法,如果不通过检测异常类型:ValidationError
                    if hasattr(self, 'clean_%s' % name):
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value)
                    except ValidationError as e:
                    self.add_error(name, e)
                    
    2、写'clean_%s'函数,和错误类型ValidationError
    3、val=self.cleaned_data.get("tel"),如果通过定义字段的条件,取值
    4、定义条件不符合再次报错:raise ValidationError("该用户已注册!")
    
    
    """
    
    class UserForm(forms.Form):
        name=forms.CharField(min_length=4,label="用户名",error_messages={"required":"该字段不能为空"},
                             widget=widgets.TextInput(attrs={"class":"form-control"})
                             )
        pwd=forms.CharField(min_length=4,label="密码",
                            widget=widgets.PasswordInput(attrs={"class":"form-control"})
                            )
        r_pwd=forms.CharField(min_length=4,label="确认密码",error_messages={"required":"该字段不能为空"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        email=forms.EmailField(label="邮箱",error_messages={"required":"该字段不能为空","invalid":"格式错误"},widget=widgets.TextInput(attrs={"class":"form-control"}))
        tel=forms.CharField(label="手机号",widget=widgets.TextInput(attrs={"class":"form-control"}))
    
    
        def clean_name(self):
    
            val=self.cleaned_data.get("name")
    
            ret=UserInfo.objects.filter(name=val)
    
            if not ret:
                return val
            else:
                raise ValidationError("该用户已注册!")
    
        def clean_tel(self):
    
            val=self.cleaned_data.get("tel")
    
            if len(val)==11:
    
                return val
            else:
                raise  ValidationError("手机号格式错误")
    
    全局:取多个校验字段:
       1、自定义函数def clean(self):覆盖父类方法,返回值和父类一致:self.cleaned_data
       2、 错误信息:raise ValidationError('两次密码不一致'),
       3、源码里
          def _clean_form(self):
            try:
                cleaned_data = self.clean()
            except ValidationError as e:
                self.add_error(None, e)
            else:
                if cleaned_data is not None:
                    self.cleaned_data = cleaned_data
                    
       self.add_error(None, e)
       错误信息格式:{"__all__":e},不是第一次forms组件校验失败的格式{字段:错误信息}
       所以需要forms.errors.get("__all__"),
       错误信息是个列表:print("error",form.errors.get("__all__")[0])
       
       errors=for m.errors.get("__all__")赋值给模板,{{ errors.0 }}
    
        def clean(self):
            pwd=self.cleaned_data.get('pwd')
            r_pwd=self.cleaned_data.get('r_pwd')
            
            # 如果第一次密码没输会提示forms验证错误信息, 确认密码执行还会再报错两次密码不一致,
            #  所以先判断有没有 :if pwd and r_pwd:
            if pwd and r_pwd:
                if pwd==r_pwd:
                    return self.cleaned_data
                else:
                    raise ValidationError('两次密码不一致')
            else:
                return self.cleaned_data
    

    源码位置:

    is_valid 
    self.errors  
    self.full_clean() 
    		self._clean_fields()
            self._clean_form()
            self._post_clean()
    
    展开全文
  • (5)Django框架学习-Forms

    千次阅读 2015-08-28 00:30:43
    Forms HTML form是交互网页的支柱。下面来学习一下有关使用Django处理用户提交的表单数据,验证等功能。 我们将讨论HttpRequest和Form对象。 request中包含的信息 在views.py中的每一个用于显示页面的...

    Forms

    HTML form是交互网页的支柱。下面来学习一下有关使用Django处理用户提交的表单数据,验证等功能。
    我们将讨论HttpRequest和Form对象。
    • request中包含的信息
    在views.py中的每一个用于显示页面的函数都需要以request作为第一个函数参数。request包含了一些有用
    的信息,如:
    request.path               除去了域名和端口的访问路径,
    request.get_host       域名+端口信息
    request.get_full_path()   所有路径,包含传递的参数
    requets.is_secure()     是否使用https进行链接
    还有一个特别的属性request.META,它是一个dict类型,包含了所有HTTP header信息,不过也要根据用户
    的实际环境来决定。如
    HTTP_REFERER
    HTTP_USER_AGENT   用户使用的浏览器信息
    REMOTE_ADDR     用户的IP,如果使用代理,也可以显示出来
    (有很多属性,只是截图了一些)
      
    并不是每一个用户提交的头信息都相同,所以在读取的时候,要考虑一些异常情况,比如取不到相应的值的情况。
    可以使用try...except,也可以使用dict.get(key, default)中默认返回为预设值的方法。
    def ua_display_good1(request):
        try:
            ua = request.META['HTTP_USER_AGENT']
        except KeyError:
            ua = 'unknown'
        return HttpResponse("Your browser is %s" % ua)
     
    def ua_display_good2(request):
        ua = request.META.get('HTTP_USER_AGENT', 'unknown')
        return HttpResponse("Your browser is %s" % ua)
     
    除了以上的这些元数据的信息,HttpRequest对象还包括两个属性包括了用户提交的数据:
    request.GET和request.POST。它们都是dictionary-like对象。意思就是说可以像dict那样
    操作,但不是dict,还有一些dict没有的操作。
     
    下面构造一个用于用户搜索的简单form例子。
    #template/search_form.html
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
    #template/search_results.html
    <p>Your searched for '{{ query }}'
    {% if books %}
        {% for book in books %}
            <li>{{ book.title }}</li>
        {% endfor %}
    {% else %}
        <p>No books found.
    {% endif %}
    # urls.py
    from django.conf.urls import patterns, include, url
    from books.views import hello, search_form, search
    urlpatterns = patterns('',
        url(r'^search-form/$', search_form),
        url(r'^search/$'search),                     
    )
    #views.py
    from django.http import HttpResponse
    from django.shortcuts import render_to_response
    from books.models import Book

    def search_form(request):
        return render_to_response('search_form.html')

    def search(request):
        if 'q' in request.GET:#GET是一个dict,使用文本框的name作为key
        #在这里需要做一个判断,是否存在提交数据,以免报错
            q = request.GET['q']
            #使用lookup后缀,意思为书名不区分大小写,包含q就可以
            books = Book.objects.filter(title__icontains=q)
            return render_to_response('search_results.html', {'books' : books, 'query':q})
        else:
            message = 'You submitted an empty form.'
            #只是简单的返回一个response对象,因为没有使用模块,所以也不用渲染数据Context
            return HttpResponse(message)
     
    还有一点,form中的action属性如果为空的,代表提交数据到当前页面。    
     
    关于表单验证
    可以在server端进行,有时会加重server负担,也可以使用Javascript在client端进行。有一点需要注意的是,
    即使你使用了javascript在client进行了验证,还是需要在server端对用户提交的数据进行审查,比如有些人
    会在浏览器中禁用javascript,也有些人会来搞注入攻击。总之,不能相信用户提交的提交,进行防御性编码。
     
    关于使用重定向
    你应当总是在一个成功处理POST请求之后进行redirect,这样可以避免用户多次点击提交按钮带来的二次请求
    问题,有时会造成不好的后果,如向数据库插入重复记录等。
    from django.http import HttpResponseRedirect
    return HttpResponseRedirect('/success/')
    • 使用Django的form system来简化表单工作
    在app文件夹下创建forms.py,其实在哪里创建都可以:
    from django import forms
     
    class ContactForm(forms.Form):
        subject = forms.CharField()
        email = forms.EmailField(required=False)
        message = forms.CharField()
    form的定义和model类的定义很像。我们可以使用python manage.py shell来查看form类的信息。
     
    可以看到打印出来的f的信息其实是网页格式的。
    也可以改变默认表格的格式。
     
    这里的<table>,<ul>都没有包含在输出里,所以可以自由地添加行等。
    除了打印出整个form的HTML内容,还可以打印出局的字段的内容。
     
     
    还可以使用form类进行验证,使用dict对form类进行初始化。
    >>> f = ContactForm({'subject': 'Hello', 'email': 'adrian@example.com', 'message': 'Nice'})
    >>> f.is_bound #是否绑定表单类
    True
    >>> f.is_valid() #数据内容是否合法
    True
    当数据全部合法时,可以使用clean_data这个属性,用来得到经过'clean'格式化的数据,会所提交过
    来的数据转化成合适的Python的类型。
     
    如何在view中使用form类
    # views.py

    from django.shortcuts import render_to_response
    from mysite.contact.forms import ContactForm

    def contact(request):
        #可以不写,因为python中if中定义的变量,也可以在整个函数中可见    
        form = None 
        if request.method == 'POST':
            form = ContactForm(request.POST)
            if form.is_valid():
                cd = form.cleaned_data
                send_mail(
                    cd['subject'],
                    cd['message'],
                    cd.get('email''noreply@example.com'),
                    ['siteowner@example.com'],
                )
                return HttpResponseRedirect('/contact/thanks/')#需要在urls.py中配置路径
        else:
            form = ContactForm()
        return render_to_response('contact_form.html', {'form': form})
     
    # contact_form.html
     
    <html>
    <head>
        <title>Contact us</title>
    </head>
    <body>
        <h1>Contact us</h1>

        {% if form.errors %}
            <p style="color: red;">
                {# pulralize 是filter,用来判断是否为添加's'来表示单词的复数形式#}
                Please correct the error{{ form.errors|pluralize }} below.
            </p>
        {% endif %}

        <form action="" method="post">
            <table>
                {# 可以使用as_ul, as_p来改变格式 #}
                {{ form.as_table }}
            </table>
            <input type="submit" value="Submit">
        </form>
    </body>
    </html>
     
    在构造form的时候,还可以改变字段的构造参数
    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100)
        email = forms.EmailField(required=False)
        message = forms.CharField(widget=forms.Textarea)
    还可以给form类添加默认值
    form = ContactForm(
                initial={'subject': 'I love your site!'}
            )
     
    给form类自定义验证规则,如果想要重用验证机制,可以单独创建新的字段类,重新写它的验证方法。
    一般的可以直接在form类加入clean_字段名的方法,Django会自动查找以clean_开头的函数名,并会在
    验证该字段的时候,运行这个函数。
    from django import forms

    class ContactForm(forms.Form):
        subject = forms.CharField(max_length=100)
        email = forms.EmailField(required=False)
        message = forms.CharField(widget=forms.Textarea)

        def clean_message(self):
            message = self.cleaned_data['message']
            num_words = len(message.split())
            if num_words < 4:
                raise forms.ValidationError("Not enough words!")
            return message
    在自定义的验证函数中,我们必须显示的返回字段名的内容,否则会带来表单数据丢失。
     
    可以改变字段的label显示的名称
    email = forms.EmailField(required=False, label='Your e-mail address')
    展开全文
  • forms

    2019-07-07 21:50:40
    添加新博客 编辑本博客 yuan先生博客 转载于:https://www.cnblogs.com/yaya625202/p/9339589.html

    添加新博客 编辑本博客

    yuan先生博客

    转载于:https://www.cnblogs.com/yaya625202/p/9339589.html

    展开全文
  • 文章目录1、forms组件1.1、定义1.2、forms校验字段功能1.2.1、定义类,类里写要校验的字段1.2.2、视图函数1.3、forms渲染模板功能1.3.1、视图函数1.3.2、模板 1、forms组件 1.1、定义 1、注册功能,登录功能,前端...

    1、forms组件

    1.1、定义

    1、注册功能,登录功能,前端需要校验(字段长度,邮箱是否合法…)
    2、前端校验可以没有,后端校验是必须的,使用传统方式if判断写的很多
    3、借助于forms组件,可以快速实现字段的校验,需要导入:from django.forms import Form

    1.2、forms校验字段功能

    1.2.1、定义类,类里写要校验的字段
    class MyForm(forms.Form):
        # 校验这个字段,最大长度是32,最小长度是3
        name = forms.CharField(required=False, max_length=32, min_length=3,label='用户名')
        email = forms.EmailField(label='邮箱')
        age=forms.IntegerField(max_value=130,min_value=0,label='年龄')
    
    1.2.2、视图函数
    # 需要导入刚才定义的类
    from myforms import MyForm
    
    def check_user_info(request):
        # 数据可以是从前端传过来的,也可以是自己后台的数据
        # 校验数据是否合法
        # 实例化得到form对象,把要校验的数据传入
        # 校验数据只校验类中出现的字段 多传不影响 多传的字段直接忽略
        # 校验数据 默认情况下 类里面所有的字段都必须传值
        # 也就意味着校验数据的时候 默认情况下数据可以多传但是绝不可能少传
        form=myforms.MyForm(request.POST)
        
        # 校验数据,判断数据是否合法: form.is_valid() 返回布尔类型,该方法只有在所有的数据全部合法的情况下才会返回True
        if form.is_valid():
        	# 成功
            print('校验通过')
            # 查看所有校验通过的数据
            print(form.cleaned_data)  # 不一定是上面传入的数据
        else:
        	# 校验失败
            print(form.cleaned_data)
            # 查看所有不符合校验规则以及不符合的原因
            print(form.errors)  # 默认是form.errors.as_ul()  是为了渲染模板
            print(type(form.errors))  # from django.forms.utils import ErrorDict
            
            # 重写了__str__
            print(form.errors.as_json())
            print(form.errors.as_data())
        return HttpResponse('ok')
    

    1.3、forms渲染模板功能

    1.3.1、视图函数
    def check_user_info(request):
        if request.method == 'GET':
            form=myforms.MyForm()
            return render(request,'check_user_info.html',{'form': form})
        elif request.method == 'POST':
            # 数据校验
            form=myforms.MyForm(request.POST)
            if form.is_valid():
                print('校验通过,存数据库')
            else:
                print(form.errors.as_data())
                print('校验失败,返回错误')
            return HttpResponse('ok')
    
    1.3.2、模板
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <hr>
    <h1>手动创建模板</h1>
    <form action="" method="post">
        <p>用户名: <input type="text" name="name"></p>
        <p>邮箱: <input type="text" name="email"></p>
        <p>年龄: <input type="text" name="age"></p>
        <p><input type="submit" value="提交"></p>
    </form>
    
    <h1>半自动渲染模板1</h1>
    <form action="" method="post">
        <p>用户名: {{ form.name }}</p>
        <p>邮箱: {{ form.email }}</p>
        <p>年龄: {{ form.age }}</p>
        <p><input type="submit" value="提交"></p>
    </form>
    
    <h1>半自动渲染模板2(使用频率高)</h1>
    <form action="" method="post">
        <p>{{ form.name.label }}: {{ form.name }}</p>
        <p>{{ form.email.label }}: {{ form.email }}</p>
        <p>{{ form.age.label }}: {{ form.age }}</p>
        <p><input type="submit" value="提交"></p>
    </form>
    
    <h1>半自动渲染模板3(使用频率高)</h1>
    <form action="" method="post">
        {% for foo in form %}
           <p>{{ foo.label }}: {{ foo }}</p>
        {% endfor %}
        <p><input type="submit" value="提交"></p>
    </form>
    
    <h1>全自动</h1>
    <form action="" method="post">
    	<!--使用ul渲染-->
    	{{ form.as_ul }}
    	<!--使用p标签渲染-->
    	{{ form.as_p }}
    	<!--使用table渲染-->
    	<table>
    		{{ form.as_table }}
    	</table>
        <p><input type="submit" value="提交"></p>
    </form>
    </body>
    </html>
    

    1.4、forms渲染错误信息

    1.4.1、视图函数
    def register(request):
        if request.method == 'GET':
            form=myforms.MyForm()
            return render(request, 'register.html',{'form':form})
        else:
            form=myforms.MyForm(request.POST)
            if form.is_valid():
            	# 校验成功模拟跳转百度页面
                return redirect('http://www.baidu.com')
            else:
                return render(request, 'register.html',{'form':form})
    
    1.4.2、模板
    <form action="" method="post" novalidate>
    	{% for foo in form %}
    	<div class="form-group">
            <label for="">{{ foo.label }}</label>
                {{ foo }}
                <span class="text-danger pull-right">{{ foo.errors }}</span>
            </div>
    	{% endfor %}
    	<div class="text-center">
    		<input type="submit" value="提交" class="btn btn-danger">
    	</div>
    </form>
    

    1.5、forms组件参数配置

    定制模板中的显示样式,及配置类,比如widget=widgets.PasswordInput(attrs={'class': 'form-control'})
    错误信息中文显示,比如error_messages={'min_length': '字段长度过短'}
    
    from django.core.exceptions import ValidationError
    from django.forms import widgets
    
    class MyForm(forms.Form):
    	# 用户名至少3位,最多16位
        username = forms.CharField(min_length=3, max_length=16, label='用户名',
                                   widget=widgets.TextInput(attrs={'class': 'form-control'}),
                                   error_messages={'required': '用户名必传', 'min_length': '用户名至少3位', 'max_lenth': '用户名最多16位'})
        age = forms.IntegerField(min_value=1, max_value=130, label='年龄',
                                 widget=widgets.TextInput(attrs={'class': 'form-control'}), error_messages={
                'required': '年龄必传', 'min_value': '最少1岁', 'max_value': '最大130岁'})
        password = forms.CharField(min_length=3, max_length=16, label='密码',
                                   widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        re_password = forms.CharField(min_length=3, max_length=16, label='确认密码',
                                      widget=widgets.PasswordInput(attrs={'class': 'form-control'}))
        email = forms.EmailField(label='邮箱', widget=widgets.TextInput(attrs={'class': 'form-control'}))
        text = forms.CharField(label='个人简介', widget=widgets.Textarea(attrs={'class': 'form-control'}))
        date = forms.CharField(label='出生日期', widget=widgets.DateInput(attrs={'class': 'form-control'}))
    

    1.6、钩子函数(HOOK)

    在特定的节点自动触发完成响应操作
    钩子函数在forms组件中就类似于第二道关卡,能够让我们自定义校验规则,钩子函数在类里面书写方法即可
    在forms组件中有两类钩子
    	1、局部钩子
    		当你需要给单个字段增加校验规则的时候可以使用
    	2、全局钩子
      		当你需要给多个字段增加校验规则的时候可以使用
    
    1.6.1、局部钩子
    校验用户名中不能含有“xxx”
    
    局部钩子的使用
    1、在自定义的Form类中写 clean_字段名
    2、取出字段的真正值,name=self.cleaned_data.get('username')
    3、判断自己的规则,如果判断失败,抛出ValidationError或使用self.add_error
    4、如果通过,return name
    
    def clean_username(self):
        username = self.cleaned_data.get('username')
        if username.startswith('xxx'):
        	# 方式一 抛出异常ValidationError
            # raise ValidationError('不能以xxx开头')
    		
    		# 方式二 为某个字段添加错误信息
            self.add_error('username', '不能以xxx开头')
        else:
        	# 校验通过,返回username
            return username
    
    1.6.2、全局钩子
    校验两次密码填写是否一致
    
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password != re_password:
        	# 方式一 抛出异常ValidationError
        	# raise ValidationError('两次密码不一致')
    
    		# 方式二 为某个字段添加错误信息
            self.add_error('re_password', '两次密码不一致')
        # 校验通过,返回
        return self.cleaned_data
    

    2、forms组件校验源码

    1、form_obj.is_valid()
    def is_valid(self):
            """
            Returns True if the form has no errors. Otherwise, False. If errors are
            being ignored, returns False.
            """
       # 如果is_valid要返回True的话 那么self.is_bound要为True self.errors要为Flase
       return self.is_bound and not self.errors
    
    2、self.errors: 这个self指的是BaseForm类,errors使用了property修饰,其实是一个方法
    3、self.full_clean(): 这个self指的是BaseForm类
    4、forms组件所有的功能基本都出自于full_clean方法
    def full_clean(self):
      	self._clean_fields()  # 校验字段 + 局部钩子
        self._clean_form()  # 全局钩子
        self._post_clean()
    
    # 校验字段 + 局部钩子
    self._clean_fields: 这个self指的是BaseForm类
    		for name, field in self.fields.items():
                try:
                    # 字段自己的校验(比如最大值,最小值,是不是邮箱格式等)
                    value = field.clean(value)
                    self.cleaned_data[name] = value
                    if hasattr(self, 'clean_%s' % name): # 反射判断有没有clean_字段名,局部钩子
                        value = getattr(self, 'clean_%s' % name)()
                        self.cleaned_data[name] = value
                except ValidationError as e:
                    self.add_error(name, e)
                    
    # 全局钩子              
    self._clean_form: 这个self指的是BaseForm类
    	 try:
            cleaned_data = self.clean()  # self.clean执行的是自己类的clean方法
         except ValidationError as e:
            self.add_error(None, e)
    

    总结
    is_valid() -->self.errors–>self.full_clean()
    第一步:self._clean_fields()方法中先会校验form中定义的第一个字段,比如name,然后校验max_lenth,min_length等,校验成功后会查看是否有局部钩子clean_data,如果有就会执行,执行完毕后执行第二步,如果没有直接执行第二步;

    第二步:再去校验第二个字段,重复第一步,先校验内置的,再校验局部钩子;

    第三步:所有字段都校验通过(字段和局部钩子都成功),校验全局钩子

    展开全文
  • forms.Form和forms.ModelForm

    2019-09-12 17:12:02
    forms.ModelForm是forms.Form的升级版 forms.Form验证规则 2.1 forms.py 2.2 view.py 把我们写的UserResetForm导入到view.py 2.3 模板 forms.ModelForm验证规则 3.1 models.py 3.2 forms.py就用上面模型类...
  • document.forms用法示例介绍

    万次阅读 2017-04-13 01:53:57
    forms 返回一个集合 (一个HTMLCollection对象),包含了了当前文档中的所有form元素. 语法 var collection = document.forms; document.forms['exportServlet'].submit(); (1)document.forms:表示获取当前页面...
  • document.forms的用法(详解)

    千次阅读 2019-03-22 17:05:24
    document.forms 表示获取当前页面的所有表单 document.forms[0] 表示获取当前页面的第一个表单 document.forms[‘exportServlet’] 表示获取当前页面的name="exportServlet"的表单 document.forms[...
  • 前段时间做个小程序,需要用到第三方的ocx控件调用时,引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常 以下是解决办法((System.ComponentModel.ISupportInitialize)(this.myClient...
  • 下面这种方式是一种post+get请求...为了避免中文乱码问题,强烈建议不要使用下面这种方式:document.forms[0].method="post"; document.forms[0].action="/testManage_editTest?pageNow="+pageNow; document.forms[0].s
  • 项目——添加引用——搜索System.Windows.Forms——勾选“System.Windows.Forms”项,确定,即可。
  • 1 到unity安装目录拷贝System.Windows.Forms.dll到unity工程下Assets下的新建文件夹Plugins中,这个引用在Unity安装目录\Editor\Data\Mono\lib\mono\2.0 ,不要拷贝错了,C盘Microsoft.NET下也有这引用,同时unity...
  • document.forms[].submit()使用介绍

    千次阅读 2016-09-14 19:00:00
    document.forms['exportServlet'].submit();  (1)document.forms:表示获取当前页面的所有表单  (2)document.forms[0]:表示获取当前页面的第一个表单  (3)document.forms['exportServlet']:表示获取...
  • document.forms[0].submit(); document.forms['exportServlet'].submit();  (1)document.forms:表示获取当前页面的所有表单  (2)document.forms[0]:表示获取当前页面的第一个表单  (3)docu
  • CS0433: 类型“Microsoft.Reporting.WebForms.ReportViewer”同时存在于“c:/WINDOWS/assembly/GAC_MSIL/Microsoft.ReportViewer.WebForms/8.0.0.0__b03f5f7f11d50a3a/Microsoft.ReportViewer.WebForms.dll”和“c:/...
  • C#使用OleDB操作ACCESS Provider=Microsoft.Jet.OLEDB.4.0;Data Source=” + NewFileName + “;User Id=uid;Jet OLEDB:Database Password=pwd;”;完整错误信息: {System.InvalidOperationException: 无效操作。...
  • django表单forms实现下拉列表(Select)

    千次阅读 2018-06-01 20:23:48
    from django import forms from blog.models import * CATEGORY = Category.objects.all() class ArticleForm(forms.Form): title = forms.CharField(required=True, max_length=50) content = forms.Char...
  • Django 表单中 下拉框ChoiceField 的使用

    万次阅读 2013-04-24 10:20:53
    Django 表单中 下拉框ChoiceField 的使用,配合模板 from.py from django import forms class SysConfigForm... DatabaseType=forms.ChoiceField(choices=[('sqlserver','SQLServer'),('oracle','Oracle')])
  • Sys.WebForms.PageRequestManagerParserErrorException: 无法分析从服务器收到的消息,之所以出现此错误,常见的原因是:通过调用Response.Write()修改相应时,将启用响应筛选器、HttpModules或服务器追踪。 ...
  • Application.OpenForms

    千次阅读 2007-12-04 07:53:00
    .NET FX 2.0 WinForm 提供了 Application.OpenForms 属性,便于我们获取已 "打开" 的窗体。相信下面的代码你非常熟悉。public partial class Form1 : Form{ public Form1() { InitializeComponent(); } p
  • JAVA 与C# API的比较

    千次阅读 2010-09-23 01:59:00
1 2 3 4 5 ... 20
收藏数 271,983
精华内容 108,793
关键字:

forms