Python(五十五)状态保持以及表单

2022-02-11  本文已影响0人  Lonelyroots

从2021年9月2日发文至今,Python系列(包括代码在内)共计106125个字、五十五篇!

1. session(会话)保存状态

1.http协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态。
2.客户端与服务器端的一次通信,就是一次会话实现状态保持的方式:在客户端或服务器端存储与会话有关的数据。
3.存储方式包括cookie、session,会话一般指session对象。
4.使用cookie,所有数据存储在客户端,注意不要存储敏感信息。
5.使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储session_id。
6.状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据。

  • 注意:不同的请求者之间不会共享这个数据,与请求者一一对应。

1.1. 使用session

启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象

  • get(key, default=None):根据键获取会话的值
  • flush():删除当前的会话数据并删除会话的Cookie

1.2.会话过期时间

  • set_expiry(value):设置会话的超时时间
  • 如果没有指定,则两个星期后过期
  • 如果value是一个整数,会话将在values秒没有活动后过期
  • 若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
  • 如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
  • 如果value为None,那么会话永不过期

form_session/views.py:

from django.shortcuts import render
from django.views import View
from django.shortcuts import redirect,reverse

# Create your views here.

def home(request):
    # 从session里面去获取相关与username的值,通过username变量去接收,如果没有值,将”用户未登录“的字符串赋值给username
    username = request.session.get('username','用户未登录')
    if username == '用户未登录':
        return redirect('login')        # 这里重定向可以不写reverse
    return render(request,'form_session/home.html',context={
        'username':username
    })

class LoginTest(View):
    def get(self,request):
        return render(request,'form_session/login.html')

    def post(self,request):
        username = request.POST.get('user')        # 这里和模板文件login第一个input里的name值保持一致
        request.session['username'] = username      # 保存用户登录状态
        request.session.set_expiry(0)       # 0表示关闭浏览器后过期
        return redirect(reverse('home'))      # 如果渲染页面,需要携带数据用render,简单的页面跳转用重定向

def logout(request):
    request.session.flush()     # 删除当前会话的数据并删除cookie
    return redirect('home')

form_session/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('home/',views.home,name='home'),
    path('login/',views.LoginTest.as_view(),name='login'),
    path('logout/',views.logout,name='logout'),
]

templates/form_session/login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录页面</title>
</head>
<body>

<form action="{% url 'login' %}" method="post">
    {% csrf_token %}
    <input type="text" placeholder="请输入用户名" name="user"><br>
    <input type="submit" value="登录">
</form>

</body>
</html>

templates/form_session/home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

欢迎{{ username }}登录页面    {# 这里的username是views里context传的键 #}
<a href="{% url 'logout' %}">注销</a>

</body>
</html>

注: 使用session之前需要先执行makemigrations,migrate的模型映射文件命令,在数据库中有生成django_session的表格。

2. django的form表单

2.1. form表单的引用

登录页面和注册页面都会用到form表单来提交数据,当数据提交到后台后, 需要在视图函数中去验证数据的合法性,而django中提供了一个form表单的功能, 这个表单可以用来验证数据的合法性还可以用来生成HTML代码。

2.2. form表单的使用

1.创建一个forms.py的文件,放在指定的app当中,然后在里面写表单。
2.表单是通过类实现的,继承自forms.Form,然后在里面定义要验证的字段。
3.在表单中,创建字段跟模型是一模一样的,但是没有null=True或者blank=True等这几种参数了,有的参数是required=True/False。
4.使用is_valid()方法可以验证用户提交的数据是否合法,而且HTML表单元素的name必须和django中的表单的name保持一致,否则匹配不到。
5.is_bound属性:用来表示form是否绑定了数据,如果绑定了,则返回True,否则返回False。
6.cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据。

2.3. form表单例子

可以生成前端页面,也可以用来验证数据的合法性。

form_session/forms.py:

from django import forms

class RegisterForm(forms.Form):
    # 用户名,默认情况下是text文本框
    username = forms.CharField(max_length=30,min_length=4,
                               widget=forms.TextInput(attrs={'placeholder':'请输入用户名'})
                               )
    # 密码,这里要将文本框改成密码框
    password = forms.CharField(max_length=16,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'})
                               )
    # 确认密码
    password_confirm = forms.CharField(max_length=16,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请再次输入密码'})
                               )
    # 邮箱
    email = forms.EmailField()

2.4. form表单中的参数

max_length:最大长度
min_length:最小长度
widget:负责渲染网页上HTML 表单的输入元素和提取提交的原始数据
attrs:包含渲染后的Widget 将要设置的HTML 属性
error_messages:报错信息
注:虽然form可以生成前端页面,但这个功能实际用的少,主要是是用form表单的验证功能。

2.5. 注册的视图函数

form_session/views.py:

# 但凡是后台都需要写在视图函数里进行获取,而不能直接写在模板文件里
from .forms import RegisterForm
from .models import UserModel
from django.http import HttpResponse
from django.shortcuts import render,redirect,reverse
from django.views import View

class RegisterTest(View):
    def get(self,request):
        form = RegisterForm()
        return render(request,'form_session/register.html',context={'form':form})

    def post(self,request):
        form = RegisterForm(request.POST)      # 获取表单的所有数据
        if form.is_valid():     # 判断数据是否合法,True表示合法,这里的合不合法主要指邮箱@后的格式
            # 保存用户提交的数据
            username = form.cleaned_data.get('username')
            pwd = form.cleaned_data.get('password')
            pwd_confirm = form.cleaned_data.get('password_confirm')
            email = form.cleaned_data.get('email')
            if pwd == pwd_confirm:
                # 两次密码保持一致,则保存
                UserModel.objects.create(username=username,password=pwd,email=email)
                return HttpResponse('注册成功!欢迎您使用该网站')
            else:
                return HttpResponse('注册失败!请确认两次密码输入一致!')
        else:
            return HttpResponse('请输入合法的数据!')

templates/form_session/register.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册页面</title>
</head>
<body>

<form action="{% url 'register' %}" method="post">
    {% csrf_token %}
    {#后台传输过来的数据需要在前端进行显示,使用的是模板变量#}
{% comment %}    {# 默认是内联标签,都在同一行进行显示 #}
    {{ form }}{% endcomment %}
    {#  以p标签单独成行进行显示  #}
    {{ form.as_p }}
    <input type="submit" value="注册">
</form>

</body>
</html>

3. 登录注册案例

form_session/forms.py:

# (十一、状态保持以及表单:form表单)

from django import forms

class RegisterForm(forms.Form):
    # 用户名,默认情况下是text文本框
    username = forms.CharField(max_length=30,min_length=4,
                               widget=forms.TextInput(attrs={'placeholder':'请输入用户名'})
                               )
    # 密码,这里要将文本框改成密码框
    password = forms.CharField(max_length=16,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'})
                               )
    # 确认密码
    password_confirm = forms.CharField(max_length=16,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请再次输入密码'})
                               )
    # 邮箱
    email = forms.EmailField()



# (十二、中间件和上下文处理器)

from django import forms

class LoginForm(forms.Form):
    # 用户名,默认情况下是text文本框
    username = forms.CharField(max_length=30,min_length=4,
                               widget=forms.TextInput(attrs={'placeholder':'请输入用户名'})
                               )
    # 密码,这里要将文本框改成密码框
    password = forms.CharField(max_length=16,min_length=6,
                               widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'})
                               )

form_session/views.py:

# 但凡是后台都需要写在视图函数里进行获取,而不能直接写在模板文件里
from .forms import RegisterForm
from .models import UserModel
from django.http import HttpResponse
from django.shortcuts import render,redirect,reverse
from django.views import View

class RegisterTest(View):
    def get(self,request):
        form = RegisterForm()
        return render(request,'form_session/register.html',context={'form':form})

    def post(self,request):
        form = RegisterForm(request.POST)      # 获取表单的所有数据
        if form.is_valid():     # 判断数据是否合法,True表示合法,这里的合不合法主要指邮箱@后的格式
            # 保存用户提交的数据
            username = form.cleaned_data.get('username')
            pwd = form.cleaned_data.get('password')
            pwd_confirm = form.cleaned_data.get('password_confirm')
            email = form.cleaned_data.get('email')
            if pwd == pwd_confirm:
                # 两次密码保持一致,则保存
                UserModel.objects.create(username=username,password=pwd,email=email)
                return HttpResponse('注册成功!欢迎您使用该网站')
            else:
                return HttpResponse('注册失败!请确认两次密码输入一致!')
        else:
            return HttpResponse('请输入合法的数据!')



# (十二、中间件和上下文处理器)

from .forms import LoginForm
from .models import UserModel
from django.http import HttpResponse
from django.shortcuts import render,redirect,reverse
from django.views import View

class Db_Login(View):
    def get(self,request):
        form = LoginForm()
        return render(request,'form_session/db_login.html',context={
            'form':form
        })

    def post(self,request):
        form = LoginForm(request.POST)
        if form.is_valid():     # 判断数据是否合法,True表示合法
            # 保存用户提交的数据
            username = form.cleaned_data.get('username')
            pwd = form.cleaned_data.get('password')
            user = UserModel.objects.filter(username=username,password=pwd)     # 如果用get,找不到user就会报错,所以用filter更好
            if user:
                # 如果有这个用户
                request.session['username'] = username
                return redirect(reverse('home'))
            else:
                return HttpResponse('登录失败!用户名或密码输入有误')
        else:
            return HttpResponse('请输入合法的数据!')

templates/form_session/register.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册页面</title>
</head>
<body>

<form action="{% url 'register' %}" method="post">
    {% csrf_token %}
    {#后台传输过来的数据需要在前端进行显示,使用的是模板变量#}
{% comment %}    {# 默认是内联标签,都在同一行进行显示 #}
    {{ form }}{% endcomment %}
    {#  以p标签单独成行进行显示  #}
    {{ form.as_p }}
    <input type="submit" value="注册">
</form>

</body>
</html>

templates/form_session/db_login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录页面</title>
</head>
<body>

<form action="{% url 'dblogin' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="登录">
</form>

</body>
</html>

templates/form_session/home.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

欢迎{{ username }}登录页面    {# 这里的username是views里context传的键 #}
<a href="{% url 'logout' %}">注销</a>

</body>
</html>

form_session/urls.py:

from django.urls import path
from . import views

urlpatterns = [
    path('register/',views.RegisterTest.as_view(),name='register'),
    path('dblogin/',views.Db_Login.as_view(),name='dblogin'),
]

文章到这里就结束了!希望大家能多多支持Python(系列)!六个月带大家学会Python,私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习Python的新青年!不管多忙都会更新下去,一起加油!

Editor:Lonelyroots

上一篇下一篇

猜你喜欢

热点阅读