Django学习笔记--7

Django--Day07

  • 一、form组件
    • 1. 对比
    • 2.使用步骤
      • 2.1在视图文件中导入form组件
      • 2.2 编写类并继承form.Forms
      • 2.3 创建对象
      • 2.4 生成页面
    • 3. 优化页面
      • 3.1 在上面的步骤中,已经建立好了form组件的基本内容,要使它能够可以工作,还需要进行一些优化。
      • 3.2 如果后台校验用户信息无错误,此时可以将用户信息保存到数据库中。
      • 3.3 自定义校验规则过滤内容
      • 3.4 自定义校验格式规则
      • 3.5 自定义显示样式
  • 二、会话
    • 2.cookie
      • 2.1 cookie介绍
      • 2.2 cookie原理
      • 2.3 Cookie特点
      • 2.4 Cookie使用
      • 2.5 案例
      • 2.6 提示
    • 3.session
      • 3.1 session原理
      • 3.2 session使用(session是类字典类型)

一、form组件

forms组件主要功能是检验字段的功能,校验表单中的键值对的功能。
在python中Django 的form组件实现了如下的功能
• 生成页面可用的HTML标签
• 对用户提交的数据进行校验
• 保留上次输入内容

1. 对比

在不使用组件的情况下,我们要想对用户输入的表单的内容进行校验,需要写的代码可以是下面这种:

# 手写form校验密码
def test2(request):
    err_msg = {}
    username = ''
    password = ''
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if len(username) < 2:
            err_msg['username'] = '用户名不能小于两位'
        if len(password) < 6:
            err_msg['password'] = '密码不能少于六位'
        if not err_msg:
            models.User.objects.create(
                username=username,
                password=password,
            )
            return HttpResponse('注册成功')
    return render(request, 'app_1/register.html', {'err_msg': err_msg, 'username': username, 'password': password})

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册title>
head>
<body>
<form action="/app_1/test2/" method="POST">
    {% csrf_token %}
    <p>
        账号:<input type="text" name="username" value="{{ username }}">
        <span style="color: #ff0000;">{{ err_msg.username }}span>
    p>
    <p>
        密码:<input type="password" name="password" value="{{ password }}">
        <span style="color: #ff0000;">{{ err_msg.password }}span>
    p>
    <p><input type="submit" value="注册账号">p>
form>
body>
html>

使用form组件的情况下,我们可能只需下面这些代码:

# 使用form组件
# 1.导入form组件
from django import forms
# 2.编写form类并继承
class RegisterForm(forms.Form):
    username = forms.CharField(label='用户名')
    password = forms.CharField(label='密码')
# 3.创建视图
def register_form1(request):
    # (1).创建对象
    register_form = RegisterForm()
    # (2).返回页面
    return render(request, 'app_1/register_form.html', {'user_form': register_form})
class Register(forms.Form):
    username = forms.CharField(
        label='用户名',
        max_length=6,
        min_length=2,
        required=True,
        error_messages={
            'max_length':'最大长度为6',
            'min_length':'最小长度为2',
            'required':'必填项',
        }
    )
    password = forms.CharField(
        label='密码',
        max_length=12,
        min_length=6,
        required=True,
        error_messages={
            'max_length': '最大长度为6',
            'min_length': '最小长度为2',
            'required': '必填项',
        }
    )
def register(request):
    register_form = Register()
    if request.method == 'POST':
        register_form = Register(request.POST)
        if register_form.is_valid():
            user_dict = register_form.cleaned_data
            models.User.objects.create(
                username=user_dict.get('username'),
                password=user_dict.get('password'),
            )
            return HttpResponse('注册成功')
    return render(request,'app_1/register_form1.html',{'register_form':register_form})

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form action="/app_1/test3/" method="POST" >
    {% csrf_token %}
    {{ user_form.username.label_suffix }}{{ user_form.username.label_tag }}{{ user_form.username }}
    {{ user_form.password.label_tag }}{{ user_form.password }}
    <input type="submit" value="注册">
form>
body>
html>

2.使用步骤

使用form组件的步骤:

2.1在视图文件中导入form组件

from django import forms

Django学习笔记--7_第1张图片

2.2 编写类并继承form.Forms

username,pwd属性对应页面中的输入框前的=提示信息
pwd属性,用来修改页面上输入框前的显示内容
Django学习笔记--7_第2张图片

2.3 创建对象

Django学习笔记--7_第3张图片

2.4 生成页面

使用{{ }}方法
Django学习笔记--7_第4张图片
Django学习笔记--7_第5张图片

3. 优化页面

3.1 在上面的步骤中,已经建立好了form组件的基本内容,要使它能够可以工作,还需要进行一些优化。

在页面中加入form表单,使其能够向后台提交数据。后台中接收到数据后要进行校验,同时如果用户输入的信息与我们要求的不一致,要进行错误提示,因此下面就要编写校验功能以及错误提示功能。
视图文件中Form类:

class UserForm(forms.Form):
    username = forms.CharField(
        label='用户名',
        required=True,
        min_length=2,
        max_length=5,
        error_messages={
            'required':'不可为空',
            'min_length':'长度不可小于2',
            'max_length':'长度不可大于5'
        }
    )
    pwd = forms.CharField(
        label='密码',
        max_length = 14,
 
min_length = 6,
        error_messages={
            'required': '不可为空',
            'min_length': '长度不可小于6',
            'max_length': '长度不可大于14',
        }
    )

视图函数:

def register_form(request):
    # 创建userform对象
    user_form = UserForm()
    # 如果提交方式为post,说明用户已经通过form表单将信息提交到了后台
    if request.method=='POST':
        # 将用户传递的信息当成参数传进UserForm中,可对用户的信息进行校验
        user_form = UserForm(request.POST)
return render(request,'app_1/1.html',{'user_form':user_form})

HTML页面:

<body>
<form action="" method="post" novalidate>
{% csrf_token %}
{#novalidate的作用,去掉表单校验,因为自动生成的标签自动添加了required属性#}
    {% comment %}
        1.user_form是User类的对象
        2.user_form.username是user_form调用username属性
        3.user_form.username.label:username也是一个对象,
            username.label调用Field对象的label属性
    {% endcomment %}
    <p>
        {{ user_form.username.label_tag }}{{ user_form.username }}
        {# errors是username对象的一个列表,errors.0表示取出的第一个错误信息#}
        {# 后台校验时如果与要求不匹配则停止,抛出错误,因此同一次提交至多一个错误#}
       <label style="color: red;">{{ user_form.username.errors.0 }}label>
    p>
    <p>{{ user_form.username.label }}{{ user_form.username }}p>
    <p>{{ user_form.pwd.label }}{{ user_form.pwd }}
        <label style="color: red;">{{ user_form.pwd.errors.0 }}label>
    p>
	<p><input type="submit" value="注册提交">p>
form>
body>

Django学习笔记--7_第6张图片

3.2 如果后台校验用户信息无错误,此时可以将用户信息保存到数据库中。

只需在视图函数中增加创建数据库对象的语句即可。
Django学习笔记--7_第7张图片
代码块如下:

def register_form(request):
    # 创建userform对象
    user_form = UserForm()
    # 如果提交方式为post,说明用户已经通过form表单将信息提交到了后台
    if request.method=='POST':
        # 将用户传递的信息当成参数传进UserForm中,可对用户的信息进行校验
        user_form = UserForm(request.POST)
        if user_form.is_valid():
            # is_valid方法为:user_form对象中无错误信息
            user_data = user_form.cleaned_data
            # user_data为字典类型,以键值对的形式只存储了用户所填写的信息
            #print(user_data)#{'pwd': '1234567', 'username': '111'}
            username = user_data.get('username')
            password = user_data.get('pwd')
            models.User.objects.create(
                username=username,
                password=password,
            )
    return render(request,'app_1/1.html',{'user_form':user_form})

在此,我们已经将form组件进行用户信息验证并提交至数据库的基本代码块完成了,但是还是可以对代码块添加方法,使其功能更加完善。

3.3 自定义校验规则过滤内容

步骤:
a) 视图文件中引入模块:from django.forms import ValidationError
b) 在组件类下重写clean方法,比如名称中不能包含特殊字符

    def clean(self):
        user_data = self.cleaned_data
        username = user_data.get('username')
        if user_data != {}:
            if (username.find('@') != -1) or (username.find('#') != -1):
                error = ValidationError('名称中不能包含特殊字符')
                #第一个参数为字段名称
                self.add_error('username',error)
                raise error
            else:
                error = ValidationError('不可为空')
                self.add_error('username',error)
                raise error
       return self.cleaned_data

Django学习笔记--7_第8张图片
除了可以自定义错误类型外,我们还可以自定义form组件对用户名与密码的检验。这主要是通过正则表达式来完成的。

3.4 自定义校验格式规则

步骤:
a) 视图文件中引入模块:from django.core.validators import RegexValidator
b) 给用户增加新的信息输入框,比如手机号码。
视图类User中增加属性:

    mobile = forms.CharField(
        label='手机号码',
        required=True,
        max_length=11,
        validators=[
            RegexValidator(r'^[0-9]$','手机号码必须全为数字'),
            RegexValidator(r'^1[4-9][0-9]{9}$','手机号码为11位')
        ]
)

Django学习笔记--7_第9张图片

可以发现,在HTML中,无法为表单输入框以及表单输入文字设置样式,因为输入框并不是在网页中设置的。但是form组件中已经为我们写好了一种方法,可以方便的设置这些样式。

3.5 自定义显示样式

步骤:
a) 视图文件中引入模块:from django.forms import widgets
b) 为用户名与密码框添加样式

class UserForm(forms.Form):
    username = forms.CharField(
        label='用户名',
        required=True,
        min_length=2,
        max_length=5,
        error_messages={
            'required':'不可为空',
            'min_length':'长度不可小于2',
            'max_length':'长度不可大于5'
        },
        widget=widgets.TextInput(attrs={'class':'box1'})
    )
    pwd = forms.CharField(
        label='密码',
        max_length = 14,
        min_length = 6,
        error_messages={
            'required': '不可为空',
            'min_length': '长度不可小于6',
            'max_length': '长度不可大于14'
        },
        widget=widgets.PasswordInput(attrs={'class': 'box1'},render_value=True),
    )

Django学习笔记--7_第10张图片
在网页中

<style>
        .box1{
            color: cadetblue;
            font-size: 20px;
            border-color: red;
        }
</style>

Django学习笔记--7_第11张图片
全部代码:
models.py文件中

class User(models.Model):
    username = models.CharField(max_length=10)
    password = models.CharField(max_length=10)
    def __str__(self):
        return 'username:{},password:{}'.format(self.username,self.password)

views.py文件中

from django.shortcuts import render
from app_1 import models
from django import forms
from django.forms import ValidationError
from django.core.validators import  RegexValidator
from django.forms import widgets
class UserForm(forms.Form):
    username = forms.CharField(
        label='用户名',
        required=True,
        min_length=2,
        max_length=5,
        error_messages={
            'required':'不可为空',
            'min_length':'长度不可小于2',
            'max_length':'长度不可大于5'
        },
        widget=widgets.TextInput(attrs={'class':'box1'})
    )
    pwd = forms.CharField(
        label='密码',
        max_length = 14,
        min_length = 6,
        error_messages={
            'required': '不可为空',
            'min_length': '长度不可小于6',
            'max_length': '长度不可大于14'
        },
        widget=widgets.PasswordInput(attrs={'class': 'box1'},render_value=True),
    )
    mobile = forms.CharField(
        label='手机号码',
        required=True,
        max_length=11,
        validators=[
            RegexValidator(r'^[0-9]$','手机号码必须全为数字'),
            RegexValidator(r'^1[4-9][0-9]{9}$','手机号码为11位')
        ]
    )
    def clean(self):
        user_data = self.cleaned_data
        print(user_data)
        username = user_data.get('username')
        if user_data != {}:
            if (username.find('@') != -1) or (username.find('#') != -1):
                error = ValidationError('名称中不能包含特殊字符')
                #第一个参数为字段名称
                self.add_error('username',error)
                raise error
            else:
                error = ValidationError('不可为空')
                self.add_error('username',error)
                raise error
       return self.cleaned_data
def register_form(request):
    # 创建userform对象
    user_form = UserForm()
    # 如果提交方式为post,说明用户已经通过form表单将信息提交到了后台
    if request.method=='POST':
        # 将用户传递的信息当成参数传进UserForm中,可对用户的信息进行校验
        user_form = UserForm(request.POST)
        if user_form.is_valid():
            # is_valid方法为:user_form对象有无错误信息
            user_data = user_form.cleaned_data
            # user_data为字典类型,以键值对的形式只存储了用户所填写的信息
            #print(user_data)#{'pwd': '1234567', 'username': '111'}
            username = user_data.get('username')
            password = user_data.get('pwd')
            models.User.objects.create(
                username=username,
                password=password,
            )
    return render(request,'app_1/1.html',{'user_form':user_form})

1.html文件中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第一个页面</title>
    <style>
        .box1{
            color: cadetblue;
            font-size: 20px;
            border-color: red;
        }
    </style>
</head>
<body>
{#{{ user_form.as_p }}#}
{#也可以这样写,会将user_form中的每一行外面都包上ul标签#}
{#{{ user_form.as_ul }}#}
{#或者这样写,会将user_form中的每一行外面都包上table标签#}
{#{{ user_form.as_table }}#}
<form action="" method="post" novalidate>
    {% csrf_token %}
{#    novalidate的作用,去掉表单校验,因为自动生成的标签自动添加了required属性#}
    {% comment %}
        1.user_form是User类的对象
        2.user_form.username是user_form调用username属性
        3.user_form.username.label:username也是一个对象,
            username.label调用Field对象的label属性
    {% endcomment %}
    <p>
        {{ user_form.username.label_tag }}{{ user_form.username }}
        {# errors是username对象的一个列表,errors.0表示取出的第一个错误信息#}
        {# 后台校验时如果与要求不匹配则停止,抛出错误,因此同一次提交至多一个错误#}
        <label style="color: red;">{{ user_form.username.errors.0 }}</label>
    </p>
{#    

{{ user_form.username.label }}{{ user_form.username }}

#}
<p>{{ user_form.pwd.label }}{{ user_form.pwd }} <label style="color: red;">{{ user_form.pwd.errors.0 }}</label> </p> <p><input type="submit" value="注册提交"></p> </form> </body> </html>

二、会话

用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
1.会话过程中要解决的问题
http协议是无状态的,意为:每次都是基于一个请求一个响应.每次请求和响应都跟上次没有关系。
第一次我们登陆网站成功了,当点击购物车的时候就有可能访问的是别人的购物车。因为第一次和第二次访问是没有关系的。那怎么解决这个问题呢,我们可以在第一次请求的时候服务端制作一张身份证给浏览器,当浏览器再次请求的时候带着身份证到服务器,服务器拿到身份证后进行识别然后返回当前用户的内容。
上面的思路,我们有一个技术叫做Cookie。

2.cookie

2.1 cookie介绍

Cookie是由服务器端生成,存储在浏览器中的一段纯文本信息,建议不要存 储敏感信息如密码,因为电脑上的浏览器可能被其它人使用。

2.2 cookie原理

1) 第一次访问服务器的时候,从服务端创建cookie,响应的时候,将cookie信息存放在响应头中,返回给浏览器,浏览器接收到之后,保存到本地中
2) 当浏览器再次访问服务器的时候,浏览器会在请求头中携带与该服务器有关的所有cookie信息,一起发送到服务端
3) 服务端接收到来自浏览器的二次请求时,根据需要从多个cookie中选择自己需要的cookie信息
Django学习笔记--7_第12张图片

2.3 Cookie特点

  1. Cookie以键值对的格式进行信息的存储
  2. Cookie基于域名安全,不同域名的Cookie是不能互相访问的。
    例如访问www.baidu.com时向浏览器中写了Cookie信息,使用同一浏览器访问www.sina.com时,无法访问到www.baidu.com写的Cookie信息。
  3. 当浏览器请求某网站时,会将浏览器存储的跟网站相关的所有Cookie信息提交给网站服务器。
  4. cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。

2.4 Cookie使用

  1. 创建Cookie: 响应对象.set_cookie(key,value)
    Django学习笔记--7_第13张图片
  2. 读取Cookie: request.COOKIES[key]
    Django学习笔记--7_第14张图片
  3. 设置过期时间: max_age属性 单位s
    Django学习笔记--7_第15张图片

2.5 案例

视图函数中:

def login(request):
    if request.method == 'POST':
        #1.获取用户名与密码
        username = request.POST.get('username')
        password = request.POST.get('password')
        rm = request.POST.get('rm','dsdad')#,复选框勾选会返回on,不选没有返回值,但是可以指定默认返回值rm = request.POST.get('rm','xxx')
        # print(username,password,rm)
        # try:
        #     rm = request.POST['rm']#用中括号形式在获取不到rm时会报错误,以便捕捉,小括号不会报错
        # except MultiValueDictKeyError as e:
        #     re = 'xxx'
        if username == 'za'and password == '123':
            response =  HttpResponse('登录成功')
            if rm == 'on':
                response .set_cookie('username',username,max_age=3600*24)
            return response
    username = request.COOKIES.get('username','')

    return render(request,'app_1/login.html',{'username':username})

页面中:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>
        用户名:<input type="text" name="username" value="{{ username }}">
    p>
     <p>
        密码:<input type="password" name="password" >
    p>
     <p>
        <input type="checkbox"  name="rm">记住用户名
    p>
     <p>
        <input type="submit" value="登录" >
    p>
form>
body>
html>

Django学习笔记--7_第16张图片
注:
Django学习笔记--7_第17张图片

2.6 提示

cookie不安全,一些重要信息比如密码之类,不能存放在cookie中,有泄露风险。
上面介绍了cookie,可以将用户的一些不重要的信息保存在浏览器本地中,比如用户名,用户在某网页的搜索记录等,但是类似于用户密码,用户银行卡号,用户身份证号等敏感信息,不能存放在cookie中,因为很容易就会被人盗用。所以有另一种方法可以来保存用户的这些敏感信息,就是session。

3.session

3.1 session原理

第一次访问服务端时生成session并且生成一个随机字符串sessionid作为session的唯 一标识保存到数据库。然后将sessionid设置给cookie,由cookie返回给浏览器,当浏览器下次访问时携带sessionid 即可从数据库中查找用户的信息,并且在数据库中cookieID以及sessionkey都是以base64加密方式保存的。
Django学习笔记--7_第18张图片

3.2 session使用(session是类字典类型)

1)设置session:request.session[key]=value
2)获取session:request.session.get(key)
3)删除session:
request.session.flush() # 将整条记录删除
request.session.clear() # 删除内容部分
del request.session[‘username’]# 删除指定的key
注:Clear()只删除内容,session记录不会被删除
4) 指定session过期时间:request.session.set_expiry(2) 2s后过期
默认保存时间是14天。
同一浏览器在访问同一页面时,只会产生一条session记录
Django学习笔记--7_第19张图片

你可能感兴趣的:(学习笔记)