django之forms组件

微笑、不失礼 提交于 2020-01-13 21:27:43

django为我们提供了forms组件,可以让我们非常方便的渲染前端页面、接收及验证前端发送到后端的数据。、


forms组件不会将用户的输入清空

1.forms组件基本使用

后端代码

views.py
---------------------------------------
from django import forms
class MyRegForm(forms.Form):
    username = forms.CharField(max_length=8, min_length=3)
    password = forms.CharField(max_length=8, min_length=3)
    email = forms.EmailField()
    
def register(request):
    # 生成一个自定义的form组件对象
    form_obj = MyRegForm()
    if request.method == 'GET':
        return render(request, 'register.html', locals())
    form_obj = MyRegForm(request.POST)
    return render(request, 'register.html', locals())

前端代码

<form action="" method="post" novalidate>
    {% for input_obj in form_obj %}
    <p>
        <label for="{{ input_obj.id_for_label }}">
            {{ input_obj.label }}
        </label>
        {{ input_obj }} 
        <span>{{ input_obj.errors.0 }}</span>
    </p>
    {% endfor %}
    <input type="submit" value="提交">
</form>

后端常用方法

# form_obj本质上是根据我们定义的类封装了html代码,根据django的模版语法再渲染到html文件中
# form_obj常用方法

# 1.初始化form组件对象
form_obj = MyRegForm(request.POST)

# 2.检验form中的数据是否全部合法(可多不可少)
form_obj.is_valid()

# 3. 返回验证通过的数据。
form_obj.cleaned_data

# 4.如何获取校验失败及失败的原因
form_obj.errors

{
    'password': ['Ensure this value has at least 3 characters (it has 2).'],
    'email': ['Enter a valid email address.']
}

前端渲染

<p>第一种渲染方式:多个p标签  本地测试方便 封装程度太高了 不便于扩展</p>
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{{ form_obj.as_table }}

<p>第二种渲染方式:  扩展性较高 书写较为繁琐</p>
<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
{{ form_obj.username }}
{{ form_obj.password.label }}{{ form_obj.password }}
{{ form_obj.email.label }}{{ form_obj.email }}

<p>第三种渲染方式  推荐使用</p>
如前端代码所示,使用for循环

要注意的是forms组件在前端自带校验功能,但前端源码容易被修改,必须在后端进行校验后再对数据进行操作。

前端校验只可作为用户提示。

<form action="" method="post" novalidate>  # 取消前端校验

2.常用参数

label  # 每个input的标签内容,默认为字段名首字母大写

error_messages # 自定义报错的提示信息
username = forms.CharField(max_length=8, min_length=3,
                           error_messages={
                               'max_length': '最大长度为8',
                               'min_length': '最小长度为3',
                               'required':'不能为空',    # 为空时的提示信息
                           })

required  # 默认为True表示必填

widget # 控制type的类型及属性
password = forms.CharField(max_length=8,min_length=3,
                 widget=forms.widgets.PasswordInput(attrs={'class':'form-control c1 c2'})
                         )

3.钩子函数

django中勾子函数分为全局钩子和局部钩子。全局勾子函数一般用于字段与字段之间的关系处理,如注册时两次密码确认。局部勾子一般用于某个字段的检验,如检查用户名是否有非法字符。

def clean(self):
#    print('全局钩子....')
#    username = self.cleaned_data.get('username')
#    print(username,'全局钩子','username')
#    password = self.cleaned_data.get('password')
#    print(password, '全局钩子', 'password')

    password = self.cleaned_data.get('password')
    re_password = self.cleaned_data.get('re_password')
    if password != re_password:
        self.add_error('re_password','两次密码不一致')
        
    return self.cleaned_data # 注意return

def clean_username(self):
    print('局部钩子...')
    username = self.cleaned_data.get('username')
    if '666' in username:
        self.add_error('username','用户名不能包含666')

    return username # 如果不return,clean_data中username就为空

钩子函数的命名非常形象,钩子就像是针对钩取对象中的某个字段进行处理,然后将改字段返回,勾过来记得放回去。

钩子函数的几个注意点:

  • 勾出来的数据一定要返回
  • 局部钩子函数只有在这个局部的字段通过基本的校验才会被执行(如用户名如果不满足3-8位的要求,就不会去执行clean_username)
  • 全局钩子则无论如何都会执行

4.正则校验

from django.core.validators import RegexValidator

phone = forms.CharField(
    validators=[
        RegexValidator(r'^[0-9]+$', '请输入数字'),
        RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
    ]
)
# 其余字段做了解

5.django中的cookie和session

cookie是一种技术,大多情况下用来验证用户是否登录,在用户登录成功后返回给用户的一段随机字符串。当用户接下来访问其他页面时,可通过cookie来识别用户的身份

session是存储在服务端的key,value的一组对应关系。一个cookie对应一个value值,这个值通常是经过序列化后加密的。

cookie

#  设置cookie的方法
obj = HttpResponse('....')
obj = render('....')
obj = redirect('....')
obj.set_cookie('k1','v1')
# 删除cookie
obj.delete_cookie('k1')

# 获取cookie
request.COOKIES.get('k1')

'''
cookie中可以存放用户的一些信息
例如登录前访问的url,在登录后实现自动跳转
'''

session

# 设置session
request.session['name'] = 'egon'
request.session['password'] = '123'
'''
1.django内部会自动生成一个随机字符串
2.去django_session表中存储数据,键时随机产生的字符串,值实际上是一个序列化后的字典经过加密产生的字符串
3.将生成好的key返回给客户端浏览器存储在COOKIE 键名为sessionId中。
'''
# 获取session
request.session.get('name')
'''
1.django会自动去浏览器的cookie中查找sessionId的键的值
2.将该值去数据库django_session的表中比对
3.如果比对上了,就将对应的value值解密反序列化后封装到request.session中
'''
# 删除session
# 删除当前会话的所有Session数据
request.session.delete()

# 删除当前的会话数据并删除会话的Cookie。  推荐使用
request.session.flush() 
'''
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。
'''
# 设置会话Session和Cookie的超时时间
'''
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。
'''

6.其余不常用字段

gender = forms.ChoiceField(
    choices=((1, "男"), (2, "女"), (3, "保密")),
    label="性别",
    initial=3,
    widget=forms.widgets.RadioSelect()
)

hobby = forms.ChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=3,
    widget=forms.widgets.Select()
)
hobby1 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.SelectMultiple()
)
keep = forms.ChoiceField(
    label="是否记住密码",
    initial="checked",
    widget=forms.widgets.CheckboxInput()
)
hobby2 = forms.MultipleChoiceField(
    choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    label="爱好",
    initial=[1, 3],
    widget=forms.widgets.CheckboxSelectMultiple()
)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!