zoukankan      html  css  js  c++  java
  • Django框架4——form表单

    HTML表单一直是交互性网站的支柱,使用form组件对用户通过表单提交的数据进行访问、有效性检查以及其他处理

    从Request对象中获取数据

    URL相关信息
    属性/方法 说明 举例
    request.path 除域名外的请求路径,以正斜杠开头 "/hellow/"
    request.get_host() 主机名(比如,通常所说的域名) "127.0.0.1:8000"or"www.example.com"
    request.get_full_path() 请求路径,可能包含查询字符 "/hellow/?p=6"
    request.is_secure() 如果通过HTTPS访问,返回True,否则返回False True或False

    request.META是一个字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent(通常是浏览器的名称和版本号),常见的有:

    • HTTP_USER_AGENT 用户浏览器的user-agent
    • REMOTE_ADDR 客户端IP

    第一个Form类

    表单框架最主要的用法是,为每一个将要处理的HTML的 <Form> 定义一个Form类。 在这个例子中,我们只
    有一个 <Form> ,因此我们只需定义一个Form类。 这个类可以存在于任何地方,甚至直接写在 views.py
    文件里也行,但惯例是把Form类都放到一个文件中:forms.py。在存放 views.py 的目录中,创建这
    个文件,然后输入:

    from django import forms
    class RegisterForm(forms.Form):
        username = forms.CharField()
        pwd = forms.CharField()
        email = forms.EmailField(required = False)
    

    这看上去简单易懂,并且很像在模块中使用的语法。 表单中的每一个字段(域)作为Form类的属性,被展现
    成Field类。这里只用到CharField和EmailField类型。 每一个字段都默认是必填。要使email成为可选项,我
    们需要指定required=False。

    >>> from new.forms import RegisterForm
    >>> r = RegisterForm()
    >>> r
    <RegisterForm bound=False, valid=Unknown, fields=(username;pwd;email)>
    >>> print(r)
    
    Form对象做的第一件事是将自己显示成HTML:
    <tr><th><label for="id_username">Username:</label></th><td><input type="text" name="username" required id="id_username"></td></tr>
    <tr><th><label for="id_pwd">Pwd:</label></th><td><input type="text" name="pwd" required id="id_pwd"></td></tr>
    <tr><th><label for="id_email">Email:</label></th><td><input type="email" name="email" required id="id_email"></td></tr>
    

    RegisterForm

    为了便于访问,Django用 <label> 标志,为每一个字段添加了标签。 这个做法使默认行为尽可能合适。
    默认输出按照HTML的< table >格式,另外有一些其它格式的输出:

    >>> print(r.as_p())
    
    <p><label for="id_username">Username:</label> <input type="text" name="username" required id="id_username"></p>
    <p><label for="id_pwd">Pwd:</label> <input type="text" name="pwd" required id="id_pwd"></p>
    <p><label for="id_email">Email:</label> <input type="email" name="email" required id="id_email"></p>
    

    as_p()

    >>> print(r.as_ul())
    
    ![as_ul()](C:Users孙远新OneDriveDocumentsdjango图片as_ul().jpg)<li><label for="id_username">Username:</label> <input type="text" name="username" required id="id_username"></li>
    <li><label for="id_pwd">Pwd:</label> <input type="text" name="pwd" required id="id_pwd"></li>
    <li><label for="id_email">Email:</label> <input type="email" name="email" required id="id_email"></li>
    

    as_ul()

    >>> print(r['username'])
    <input type="text" name="username" required id="id_username">
    
    Form对象做的第二件事是校验数据
    >>> r.is_bound
    True
    

    调用任何绑定form的is_valid()方法,就可以知道它的数据是否合法。 我们已经为每个字段传入了值,因此整
    个Form是合法的:

    >>> r.is_valid()
    True
    

    如果我们不传入email值,它依然是合法的。因为我们指定这个字段的属性required=False;但是,如果留空username或pwd,整个Form就不再合法了:

    >>> r = RegisterForm({'username':'Amy','pwd':'abc13',})
    >>> r.is_valid()
    True
    >>> r = RegisterForm({'pwd':'abc13','email':'amy@123.com'})
    >>> r.is_valid()
    False
    

    如果多出其他属性,Form依然是合法的,

    >>> r = RegisterForm({'username':'Amy','pwd':'abc13','w':24})
    >>> r.is_valid()
    True
    

    查看字段的出错消息,Form实体都有一个errors属性,它为你提供了一个字段与错误消息相映射的字典表

    >>> r.errors
    {'username': ['This field is required.']}
    

    你可以逐一查看每个字段的出错消息

    >>> r['username'].errors
    ['This field is required.']
    >>> r['pwd'].errors
    []
    

    如果一个Form实体的数据是合法的,它就会有一个可用的cleaned_data属性。 这是一个包含干净的提交
    数据的字典。 Django的form框架不但校验数据,它还会把它们转换成相应的Python类型数据,这叫做清理数
    据。例如Form实体的数据合法的情况下,可以清除掉{%csrf_token%}对应的name='csrfmiddlewaretoken'

    >>> r.cleaned_data
    {'pwd': 'abc13', 'email': 'amy@123.com'}
    

    如果我们使用整数型或日期型,form框架会确保方法使用合适的Python整数型或datetime.date型对象。

    在视图中使用Form对象

    from django.shortcuts import render,redirect
    from mysite.new.forms import RegisterForm
    def register(request):
    	if request.method == 'POST':
            form = RegisterForm(request.POST)
            if form.is_valid():
                cd = form.cleaned_data
                #创建用户  User.objects.creates(**cd)
                return redirect('/home/')
            else:
                return render(request,'register.html', {'form': form,})
        form = RegisterForm()
        return render(request,'register.html', {'form': form})
    
    
    
    //register.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<form action=""  method='post' novalidate>
    			<p><label for="">用户名</label>{{form.username}}<span class="error">{{form.errors.username.0}}</span></p>
    			<p><label for="">密码</label>{{form.pwd}}<span class="error">{{form.errors.pwd.0}}</span> </p>
    			<p><label for="">邮箱</label>{{form.pwd}}<span class="error">{{form.errors.email.0}}</span> </p>
    		<input type="submit" value="确定">
    	</form>
    </body>
    </html>
    

    在浏览器中查看{{form.username}}

    <input name="username" id="id_username" required="" type="text" value="xxx">
    

    使用Form对象作为模板的好处:

    • input标签name属性的值自动与Form类中的字段保持一致,简化视图函数的代码
    • form.is_valid()为False,对输入的值进行返回,渲染在刷新面后的页面上

    input标签的type默认为"text",输入密码时要求为密文的形式,必须进行更改,此外为了页面的整体样式,还需要增加一些其他的属性

    显示逻辑
    class RegisterForm(forms.Form):
        #添加标签类名
        username = forms.CharField(label="用户名",widget=forms.TextInput(attrs={"class":"form-control"}),error_messages={'required':'该字段不能为空'})
        #
        pwd = forms.CharField(widget=forms.PasswordInput)
        email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
    
    自定义校验逻辑
    #max_length=16
    #min_length=8
    from django import forms
    from django.core.exceptions import ValidationError
    from django.contrib.auth.models import User
    class RegisterForm(forms.Form):
        username = forms.CharField(min_length=8,error_messages={'required':'该字段不能为空'})
        pwd = forms.CharField(widget=forms.PasswordInput)
        email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
        def clean_username(self):
            username = self.cleaned_data['username']
            if Userinfo.objects.filter(username = username):
            	raise ValidationError("用户名已存在!") 
            else:
                return username
    

    Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的
    方法,它将在校验时被调用。

    特别地,clean_username()方法将在指定字段的默认校验逻辑执行 之后*被调用。(本例中,在必
    填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来
    了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

    forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户

    在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换
    成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。

    指定标签

    HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签
    是"Email" 。

    自定义字段的标签

    email = forms.EmailField(required=False, label='Your e‐mail address'*)
    
    定制Form设计
    class RegisterForm(forms.Form):
        username = forms.CharField(min_length=8,error_messages={'required':'该字段不能为空'},
                                  widget=forms.TextInput(attrs={'placeholder':'输入用户名'})
        pwd = forms.CharField(widget=forms.PasswordInput)
        email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
    	'''
        def __init__(self, *args, **kwargs):
        	super().__init__(*args, **kwargs)
            for field in self.fields.values():
                field.widget.attrs.update({'class': 'form-control'})
    	'''
    
  • 相关阅读:
    【转载】零基础学Support Vector Machine(SVM)
    【转载】前向传播算法(Forward propagation)与反向传播算法(Back propagation)
    python 3.5 解决csv 读入中的'utf-8' codec can't decode办法
    pandas用法大全
    南阳理工OJ 题目168.房间安排问题与题目14.会场安排问题
    C++中IO设置数字精度问题
    C++中memset()函数笔记
    Java 编程命名规范
    数据类型内存分配--js基础
    对象--js基础
  • 原文地址:https://www.cnblogs.com/notfind/p/11761295.html
Copyright © 2011-2022 走看看