Django——forms组件

Django——forms组件

一、 forms组件

应用场景:网页注册页面,获取用户输入的用户名和密码,判断用户名和密码中不能包含规定的字段和字符(比如:黄,赌,毒),如果有,不给予页面跳转并提示错误

使用

首先,创建一个类

from django import forms

class MyRegForm(forms.form):
    #froms 里面的max_length代表的意思是最大8位数,min_ength则与子相反
    username = forms.CharField(max_length=8,min_length=3)
    password = forms.CharField(max_length=8,min_length=3)
    #email字段必须填写符合邮箱格式的数据
    email = forms.EmailField()
  1. 校验数据

    # 1.传入待校验的数据  用自己写的类 传入字典格式的待校验的数据
    form_obj = views.MyRegForm({'username':'jason','password':'12','email':'123456'})
    # 2.判断数据是否符合校验规则
    form_obj.is_valid()  # 该方法只有在所有的数据全部符合校验规则才会返回True
    False
    # 3.如何获取校验之后通过的数据
    form_obj.cleaned_data
    {'username': 'jason'}
    # 4.如何获取校验失败及失败的原因
    form_obj.errors
    {
        'password': ['Ensure this value has at least 3 characters (it has 2).'],
        'email': ['Enter a valid email address.']
    }
    # 5.注意 forms组件默认所有的字段都必须传值 也就意味着传少了是肯定不行的 而传多了则没有任何关系 只校验类里面写的字段 多传的直接忽略了
    form_obj = views.MyRegForm({'username':'jason','password':'123456'})
    form_obj.is_valid()
    Out[12]: False
    form_obj.errors
    Out[18]: {'email': ['This field is required.']}
    
    form_obj = views.MyRegForm({'username':'jason','password':'123456',"email":'123@qq.com',"hobby":'hahahaha'})
    
    form_obj.is_valid()
    Out[14]: True
    form_obj.cleaned_data
    Out[15]: {'username': 'jason', 'password': '123456', 'email': '123@qq.com'}
    form_obj.errors
    Out[16]: {}
    
  2. 渲染页面

    #forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签 不渲染按钮和form表单标签
    #渲染出来的每一个input提示信息都是类中字段首字母大写
    
    1.
    <p>第一种渲染方式:多个p标签  本地测试方便 封装程度太高了 不便于扩展</p>
        {{ form_obj.as_p }}
        {{ form_obj.as_ul }}
        {{ form_obj.as_table }}
    
    2.
    <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 }}
    
    3.
    <p>第三种渲染方式  推荐使用</p>
    {% for form in form_obj %}
    <p> {{ form.label }}{{ form }}</p>
    {% endfor %}
    
  3. 展示信息

    #如何渲染错误信息
    #前端
    <form action="" method="post" novalidate>
    {% for form in form_obj %}
    <p>
    {{ form.label }}{{ form }}
    <span>{{ form.errors.0 }}</span>  # 这个是模板语法 索引不会出现超出报错
    </p>
    {% endfor %}
    <input type="submit">
    </form>
    
    #后端
    def reg(request):
        # 1 先生成一个空的类对象
        form_obj = MyRegForm()
        if request.method == 'POST':
            # 3 获取用户数据并交给forms组件校验  request.POST
            form_obj = MyRegForm(request.POST)
            # 4 获取校验结果
            if form_obj.is_valid():
                return HttpResponse('数据没问题')
            else:
                # 5 获取校验失败的字段和提示信息
                print(form_obj.errors)
    
        # 2 直接将该对象传给前端页面
        return render(request,'reg.html',locals())
    

数据校验前后端都得有,但是前端的校验不够安全,可有可无而后端的校验则必须非常全面。

form表单取消前端浏览器自动校验功能

<form action="" methon="post" novalidate>

forms组件常用参数

label——input的提示信息

error_messages——自定义报错的提示信息

required——设置字段是否允许为空

initial——设置默认值

widget——控制type类型及属性

#常用
widget=forms.widgets.TextInput(attrs={'class':'form-control c1  c2'})
widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})

#了解
widget=forms.widgets.RadioSelect()
widget=forms.widgets.Select()
widget=forms.widgets.SelectMultiple()
widget=forms.widgets.CheckboxInput()
widget=forms.widgets.CheckboxSelectMultiple()

钩子函数

全局钩子(针对多个字段)

校验密码与确认面是否一致

# 全局钩子
def clean(self):
    # 校验密码和确认密码是否一致
    password = self.cleaned_data.get('password')
    confirm_password = self.cleaned_data.get('confirm_password')
    if not password == confirm_password:
        # 展示提示信息
        self.add_error('confirm_password','两次密码不一致')
    return self.cleaned_data

局部钩子(针对单个字段)

校验用户命中不能包含某个字段(例如:666)

# 局部钩子
def clean_username(self):
    username = self.cleaned_data.get('username')
    if '666' in username:
        self.add_error('username','光喊666是不行的')
    return username

如果你想同时操作多个字段的数据你就用全局钩子

如果你想操作单个字段的数据,你就用局部钩子

forms补充知识点

#正则校验
phone = forms.CharField(
    validators=[
        RegexValidator(r'^[0-9]+$', '请输入数字'),
        RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
    ]
)
校验输入的电话号码是否是0-9的数字,并且必须是159开头的
#这种校验用法比较广,比如校验银行卡,身份证等,百度一下即可

二、cookie与session操作

  • cookie与session的作用是为了保存信息,当你第一次登录成功之后,服务端给你返回了一个随机字符串,保存在客户端浏览器上,之后再次朝服务端发请求,只需要携带该随机字符串,服务端就就能识别当前用户身份,这个随机字符串有一个时间限制(时间可以自定定义)
  • cookie虽然是保存在客户端的浏览器上的,但是是服务端设置的。浏览器也是可以拒绝服务端的要求,不保存cookie

cookie

保存在客户端浏览器上的键值对

return HttpResponse('...')
return render(...)
return redirect(...)

#变形
obj = HttpResponse('...')
return obj

obj1 = render(...)
return obj1

obj2 = redirect(...)

#设置cookie
obj.set_cookie()
#获取cookie
request.COOKIES.get()
#删除cookie
obj.delete_cookie()

print('request.path_info:',request.path_info)  # 只拿路径部分 不拿参数
print('request.get_full_path():',request.get_full_path())  # 路径加参数
	request.path_info: /home/

    request.get_full_path(): /home/?username=jason&password=123

session

保存在服务端上的键值对

#设置
request.session['key'] = value
"""
			1.django内部会自动生成一个随机字符串
			2.去django_session表中存储数据 键就是随机字符串 值是要保存的数据(中间件干的)
			3.将生成好的随机字符串返回给客户端浏览器   浏览器保存键值对
				sessionid  随机字符串
			"""

#获取
request.session.get('key')
"""
			1.django会自动取浏览器的cookie查找sessionid键值对 获取随机字符串
			2.拿着该随机字符串取django_session表中比对数据
			3.如果比对上了 就将随机字符串对应的数据获取出来并封装到request.session供用户调用
			"""


#django中默认的session超时时间为14天
# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

# 删除当前会话的所有Session数据
request.session.delete()

# 删除当前的会话数据并删除会话的Cookie。  推荐使用
request.session.flush()
#这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。

#session是保存在服务端

django_session表你还可以把它当成是一个临时的仓库,存储数据用的,既可以存用户登录携带的信息,也可以存储其他数据。

posted @ 2020-01-13 20:13  Mr-Allen  阅读(94)  评论(0编辑  收藏  举报