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() )
来源:https://www.cnblogs.com/Ghostant/p/12189242.html