django(forms组件、cookies与session)

一、forms组件

1.功能

  - 渲染页面

  - 校验数据

  - 展示信息

需要先写一个类,该类类似于models中的表类

from django import forms

class MyRegForm(forms.Form):
    # 用户名最少3位最多8位
    username = forms.CharField(max_length=8,min_length=3)
    password = forms.CharField(max_length=8,min_length=3)
    # email字段必须填写符合邮箱格式的数据
    email = forms.EmailField()

2.如何校验数据

# 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":‘[email protected]‘,"hobby":‘hahahaha‘})
form_obj.is_valid()
Out[14]: True
form_obj.cleaned_data
Out[15]: {‘username‘: ‘jason‘, ‘password‘: ‘123456‘, ‘email‘: ‘[email protected]‘}
form_obj.errors
Out[16]: {}

数据校验一个前后端都得有,但是前端的校验弱不禁风,可有可无,而后端的校验则必须非常全面

取消校验功能

form表单取消前端浏览器自动校验功能
  <form action="" method="post" novalidate>

3.如何渲染页面

forms组件只帮你渲染获取用户输入(输入、选择、下拉、文件)的标签,不渲染按钮和form表单标签,渲染出来的每一个input提示信息都是类中字段首字母大写

<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 form in form_obj %}
    <p> {{ form.label }}{{ form }}</p>
{% endfor %}

4.如何渲染错误信息

前端

<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())

5.常用参数

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‘})

6.钩子函数

作用:实现自定义的验证功能

全局钩子:

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

局部钩子:

def clean_username(self):
    username = self.cleaned_data.get(‘username‘)
    if ‘666‘ in username:
        self.add_error(‘username‘,‘光喊666是不行的‘)
    return username

小结:如果你想同时操作多个字段的数据你就用全局钩子,如果你想操作单个字段的数据你就用局部钩子

7.其他渲染方式

radioSelect

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )

- 单选select

class LoginForm(forms.Form):
    ...
    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )

- 多选select

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )

- 单选checkbox

class LoginForm(forms.Form):
    ...
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )

多选checkbox

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

Field
    required=True,               是否允许为空
    widget=None,                 HTML插件
    label=None,                  用于生成Label标签或显示内容
    initial=None,                初始值
    help_text=‘‘,                帮助信息(在标签旁边显示)
    error_messages=None,         错误信息 {‘required‘: ‘不能为空‘, ‘invalid‘: ‘格式错误‘}
    validators=[],               自定义验证规则
    localize=False,              是否支持本地化
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀

CharField(Field)
    max_length=None,             最大长度
    min_length=None,             最小长度
    strip=True                   是否移除用户输入空白

IntegerField(Field)
    max_value=None,              最大值
    min_value=None,              最小值

FloatField(IntegerField)
    ...

DecimalField(IntegerField)
    max_value=None,              最大值
    min_value=None,              最小值
    max_digits=None,             总长度
    decimal_places=None,         小数位长度

BaseTemporalField(Field)
    input_formats=None          时间格式化   

DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12

DurationField(Field)            时间间隔:%d %H:%M:%S.%f
    ...

RegexField(CharField)
    regex,                      自定制正则表达式
    max_length=None,            最大长度
    min_length=None,            最小长度
    error_message=None,         忽略,错误信息使用 error_messages={‘invalid‘: ‘...‘}

EmailField(CharField)
    ...

FileField(Field)
    allow_empty_file=False     是否允许空文件

ImageField(FileField)
    ...
    注:需要PIL模块,pip3 install Pillow
    以上两个字典使用时,需要注意两点:
        - form表单中 enctype="multipart/form-data"
        - view函数中 obj = MyForm(request.POST, request.FILES)

URLField(Field)
    ...

BooleanField(Field)
    ...

NullBooleanField(BooleanField)
    ...

ChoiceField(Field)
    ...
    choices=(),                选项,如:choices = ((0,‘上海‘),(1,‘北京‘),)
    required=True,             是否必填
    widget=None,               插件,默认select插件
    label=None,                Label内容
    initial=None,              初始值
    help_text=‘‘,              帮助提示

ModelChoiceField(ChoiceField)
    ...                        django.forms.models.ModelChoiceField
    queryset,                  # 查询数据库中的数据
    empty_label="---------",   # 默认空显示内容
    to_field_name=None,        # HTML中value的值对应的字段
    limit_choices_to=None      # ModelForm中对queryset二次筛选

ModelMultipleChoiceField(ModelChoiceField)
    ...                        django.forms.models.ModelMultipleChoiceField

TypedChoiceField(ChoiceField)
    coerce = lambda val: val   对选中的值进行一次转换
    empty_value= ‘‘            空值的默认值

MultipleChoiceField(ChoiceField)
    ...

TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   对选中的每一个值进行一次转换
    empty_value= ‘‘            空值的默认值

ComboField(Field)
    fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])

MultiValueField(Field)
    PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用

SplitDateTimeField(MultiValueField)
    input_date_formats=None,   格式列表:[‘%Y--%m--%d‘, ‘%m%d/%Y‘, ‘%m/%d/%y‘]
    input_time_formats=None    格式列表:[‘%H:%M:%S‘, ‘%H:%M:%S.%f‘, ‘%H:%M‘]

FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
    path,                      文件夹路径
    match=None,                正则匹配
    recursive=False,           递归下面的文件夹
    allow_files=True,          允许文件
    allow_folders=False,       允许文件夹
    required=True,
    widget=None,
    label=None,
    initial=None,
    help_text=‘‘

GenericIPAddressField
    protocol=‘both‘,           both,ipv4,ipv6支持的IP格式
    unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用

SlugField(CharField)           数字,字母,下划线,减号(连字符)
    ...

UUIDField(CharField)           uuid类型

Django Form内置字段

补充:

正则校验:

phone = forms.CharField(
    validators=[
        RegexValidator(r‘^[0-9]+$‘, ‘请输入数字‘),
        RegexValidator(r‘^159[0-9]+$‘, ‘数字必须以159开头‘)
    ]
)

例子:使用form组件实现注册功能

先定义好一个RegForm类:

from django import forms

# 按照Django form组件的要求自己写一个类
class RegForm(forms.Form):
    name = forms.CharField(label="用户名")
    pwd = forms.CharField(label="密码")

再写一个视图函数:

# 使用form组件实现注册方式
def register2(request):
    form_obj = RegForm()
    if request.method == "POST":
        # 实例化form对象的时候,把post提交过来的数据直接传进去
        form_obj = RegForm(request.POST)
        # 调用form_obj校验数据的方法
        if form_obj.is_valid():
            return HttpResponse("注册成功")
    return render(request, "register2.html", {"form_obj": form_obj})

前端页面:login2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册2</title>
</head>
<body>
    <form action="/reg2/" method="post" novalidate autocomplete="off">
        {% csrf_token %}
        <div>
            <label for="{{ form_obj.name.id_for_label }}">{{ form_obj.name.label }}</label>
            {{ form_obj.name }} {{ form_obj.name.errors.0 }}
        </div>
        <div>
            <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
            {{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
        </div>
        <div>
            <input type="submit" class="btn btn-success" value="注册">
        </div>
    </form>
</body>
</html>

二、cookie

1.什么是cookie?

Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。

原理:服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。

简而言之就是指保存在客户端浏览器上的键值对

2.设置cookie

rep = HttpResponse(...)
rep = render(request, ...)

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt=‘加密盐‘, max_age=None, ...)

参数

  - key, 键

  - value=‘‘, 值

  - max_age=None, 超时时间

  - expires=None, 超时时间(IE requires expires, so set it if hasn‘t been already.)

  - path=‘/‘, Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问

  - domain=None, Cookie生效的域名

  - secure=False, https传输

  - httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

3.删除cookie

def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("user")  # 删除用户浏览器上之前设置的usercookie值
    return rep

例子:Cookie版登陆校验:

def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":
            # 已经登录的用户...
            return func(request, *args, **kwargs)
        else:
            # 没有登录的用户,跳转刚到登录页面
            return redirect("/login/?next={}".format(next_url))
    return inner

def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("password")
        if username == "xxx" and passwd == "dashabi":
            next_url = request.GET.get("next")
            if next_url and next_url != "/logout/":
                response = redirect(next_url)
            else:
                response = redirect("/class_list/")
            response.set_signed_cookie("login", "yes", salt="SSS")
            return response
    return render(request, "login.html")

cookie版登录

三、session

1.什么是session?

Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session

简而言之,Session就是保存在服务端上的键值对

2.设置session

request.session[‘key‘] = value

实现该方法内部机制:

  - django内部会自动生成一个随机字符串

  - 去django_session表中存储数据,键就是随机字符串,值是要保存的数据

  - 将生成好的随机字符串返回给客户端浏览器,浏览器保存键值对

3.获取session

request.session.get(‘key‘)

实现该方法内部机制:

  - django会自动取浏览器的cookie查找sessionid键值对,获取随机字符串

  - 拿着该随机字符串取django_session表中比对数据

  - 如果比对上了,就将随机字符串对应的数据获取出来并封装到request.session供用户调用

4.设置会话Session和Cookie的超时时间

request.session.set_expiry(value)

  - 如果value是个整数,session会在些秒数后失效。
  -  如果value是个datatime或timedelta,session就会在这个时间后失效。
  - 如果value是0,用户关闭浏览器session就会失效。
  - 如果value是None,session会依赖全局session失效策略。

django中默认的session超时时间为14天

5.删除session

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

request.session.flush():删除当前的会话数据并删除会话的Cookie,用于确保前面的会话数据不可以再次被用户的浏览器访问

补充:django中默认的session超时时间为14天

例子:Session版登陆验证

from functools import wraps

def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get("user"):
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(next_url))
    return inner

def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        if user == "alex" and pwd == "alex1234":
            # 设置session
            request.session["user"] = user
            # 获取跳到登陆页面之前的URL
            next_url = request.GET.get("next")
            # 如果有,就跳转回登陆之前的URL
            if next_url:
                return redirect(next_url)
            # 否则默认跳转到index页面
            else:
                return redirect("/index/")
    return render(request, "login.html")

@check_login
def logout(request):
    # 删除所有当前请求相关的session
    request.session.delete()
    return redirect("/login/")

@check_login
def index(request):
    current_user = request.session.get("user", None)
    return render(request, "index.html", {"user": current_user})

Session版登录验证

Session版登陆验证

原文地址:https://www.cnblogs.com/hexianshen/p/12188945.html

时间: 2024-10-08 23:52:03

django(forms组件、cookies与session)的相关文章

Django forms组件【对form舒心l了】

目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用ModelForm关键就在于model's field mapping to form's field ModelForm.save() 详解 class Meta !!!重写覆盖默认的modelField字段(即自定义一些modelform属性) form有关多选择Field的使用 form's fi

Django&mdash;&mdash;forms 组件

一.forms简介 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确.如果用户输入的内容有错误就需要在页面上相应的位置显示对应的错误信息.. Django forms组件主要功能: 生成页面可用的HTML标签 对用户提交的 数据进行校验 保留上次输入的内容 二.如何使用Django forms 1.注册功能: 渲染前端标签获取用

Django form组件 与 cookie/session

目录 一.form组件 二.cookie.session 一.form组件 1.1 以注册功能为例 注册功能 1.渲染前端标签获取用户输入 --> 渲染标签 2.获取用户输入传递到后端校验 --> 校验数据 3.校验未通过展示错误信息 --> 展示信息 ps:校验数据:前后端都可以校验,但是前端可以不做,后端必须得做!!! 1.2 校验数据 校验数据 第一步需要一个form类 from django import forms class MyForm(forms.Form): name

多对多三种创建方式 forms组件 cookie与session

1.全自动(推荐使用*)            优势:不需要你手动创建第三张表            不足:由于第三张表不是你手动创建的,也就意味着第三张表字段是固定的无法做扩展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) authors = models.ManyToManyField(to

多对多三种创建方式,forms组件,cookie和session

多对多三种创建方式 1.全自动 优点:不需要自己手动创建第三章表缺点:由于第三张表不是自己创建的,也就是说第三张表字段是固定的没有办法做扩展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) authors = models.ManyToManyField(to='Author') class Au

django ---forms组件

1 校验字段功能 2 渲染标签功能 3 渲染错误信息功能 4 组件的参数配置 5 局部钩子 6 全局钩子 回到目录 1 校验字段功能 针对一个实例:注册用户讲解. 模型:models.py class UserInfo(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) email=models.EmailField( 模版文件 复制代码 <!DOCTYPE html>

django中的cookies和session机制

0.概述 (1)为什么要有cookies和session 在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.而在现实网站中,那淘宝网来举例,用户将商品加入购物车和用户付款是不同的请求,但这个这连个请求需要是同一个用户,而这样的使用场景很多.总结来说,cookies和session一种用户识别用户身份的解决方案. (2)cookies 第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用

Django Cookies与Session组件

目录 Django Cookies与Session组件 Cookies介绍 Session介绍 Django Cookies与Session组件 Cookies介绍 Cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息. cookie的工作原理 由服务器产生内容,浏览器收到请求后保存在本地:当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是"谁"

多对多三种创建方式、forms组件、cookies与session

多对多三种创建方式.forms组件.cookies与session 一.多对多三种创建方式 1.全自动 # 优势:不需要你手动创建第三张表 # 不足:由于第三张表不是你手动创建的,也就意味着第三张表字段是固定的无法做扩展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) authors = mode