美文网首页
Python(五十五)状态保持以及表单

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

作者: Lonelyroots | 来源:发表于2022-02-11 22:16 被阅读0次

    从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

    相关文章

      网友评论

          本文标题:Python(五十五)状态保持以及表单

          本文链接:https://www.haomeiwen.com/subject/kbiwkrtx.html