欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

django快速入门(三)--视图

程序员文章站 2022-06-15 11:54:17
URLconf...

django快速入门(一)–简单学生管理系统–主体流程
django快速入门(二)–站点管理与模型
django快速入门(三)–视图
django快速入门(四)–模板,部署

URLconf

在项目mysite和应用students下都建立url.py文件是为了便于管理,一个项目可以有多个应用,把不同的应用全都塞在项目的url.py中会显得臃肿。
mysite/urls.py

from django.contrib import admin
from django.urls import path, include


urlpatterns = [
    path('admin/', admin.site.urls),
    path('students/', include('students.urls', namespace='students')),
]

mysite/students/urls.py

from django.urls import path
from . import views

app_name = 'students'
urlpatterns = [
    path('', views.index, name='index'),
    path(r'post', views.post_info, name='post_info'),
    path(r'post_result', views.receive_info, name='post_info_true')
]

urlpatterns[]列表就代表着url的路由列表,不会匹配get和post的参数。

http://127.0.0.1:8000/students/post/?1
会将students/post/匹配出来,其中students/与项目中的url按序匹配,post/与应用中的url按序匹配。
每个url参数可以有四个,正则表达式、视图函数、命名空间namespace、 名称name。

使用正则表达式

mysite/students/urls.py

from django.urls import path, re_path
from . import views

app_name = 'students'
urlpatterns = [
    re_path(r'^([0-9]+)/$', views.index, name='index'),
]

mysite/students/views.py

def index(request, number):

    aa = request.GET.get("a")
    bb = request.GET.getlist("b")
    context = {'aa': aa, 'bb': bb, 'number': number}
    return render(request, 'students/index.html', context)

http://127.0.0.1:8000/students/1233/
上面url中的1233就是通过number行参传入。

视图函数

本质就是个函数,视图可以从数据库里读取记录,可以使用一个模板引擎(比如 Django 自带的,或者其他第三方的),可以生成一个 PDF 文件,可以输出一个 XML,创建一个 ZIP 文件,使用任何想用的 Python 库。

def receive_info(request):
    uname = request.POST['uname']
    upwd = request.POST['upwd']
    post_content = request.POST['post_content']
    q = ClassStudents.objects.filter(name=uname)
    if q.count() != 1:
        page_show = "数据库没有查询到信息"
    else:
        students = q.first()
        stu_number = str(students.stu_number)
        if stu_number[-4:] == upwd:
            students.content = post_content
            students.save()
            page_show = "提交成功!"
        else:
            page_show = "你填写的学号后四位与记录不符合,请确认是否填写错误,或者与相关负责人联系!"
    context = {'page_show': page_show}
    return render(request, 'students/post_info_result.html', context)

上面一段代码其实就是从表单中接收提交的姓名和学号后四位,从数据库读取对应名字的学号,并与提交的学号后四位比对,正确则提交content的内容。
Django原生自带几个默认视图用于处理HTTP错误。
404 (page not found) 视图
500 (server error) 视图
400 (bad request) 视图

HttpRequest中的get和post

get可以用来接收url中传递的值

def index(request):
    aa = request.GET.get("a")
    bb = request.GET.getlist("b")
    context = {'aa': aa, 'bb': bb}
    return render(request, 'students/index.html', context)

get只能接收一键一值,如果传递一键多值,只会接收最后一个,如果想接收一键多值,就使用getlist
127.0.0.1:8000/students/?a=1&a=2&b=3&b=4
django快速入门(三)--视图
post则用来接收表单中提交的值
mysite/templates/students/post_info.html

<form method="post" action="{% url 'students:post_info_true'%}">
    {% csrf_token %}
    姓名:<input type="text" name="uname"/><br>
    学号后4位:<input type="password" name="upwd"/><br>
    提交的内容:<input type="text" name="post_content"/><br>
    <input type="submit" value="提交"/>

mysite/students/views.py

def receive_info(request):
    uname = request.POST['uname']
    upwd = request.POST['upwd']
    post_content = request.POST['post_content']

重定向

子类HttpResponseRedirect

from django.http import HttpResponseRedirect

def redirect(request):
    return HttpResponseRedirect('post')

在地址输入内127.0.0.1:8000/students/redirect,会自动重定向到http://127.0.0.1:8000/students/post

去除硬编码与反向解析

上面重定向的参数都是students应用中重定向的,
表单中的写法

<form method="post" action="/post">

上述的写法就是硬编码,即html中的url是写死的,一旦匹配的正则表达式发生变化,所有的html都要一起更改。这里可以使用namespace和name去除编码。

<form method="post" action="{% url 'students:post_info_true'%}">

同理,在重定向时,return HttpResponseRedirect(‘post’)这里/post也是和匹配有关,是写死的,可以使用反向解析。

from django.http import HttpResponseRedirect
from django.urls import reverse

def redirect(request):
    return HttpResponseRedirect(reverse('students:post'))

def redirect(request):
    return HttpResponseRedirect(reverse('students:index', args=(123, )))

状态保持,cookie和session

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,不能放入用户B或用户C的购物车内,这不属于同一个会话。
而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
session在django-admin startproject创建的项目默认启用
启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
url

from django.urls import path, re_path
from . import views

app_name = 'students'
urlpatterns = [
    path('', views.index, name='index'),
    path('redirect', views.redirect, name='redirect'),
    re_path(r'^([0-9]+)/$', views.index, name='index'),
    path(r'post', views.post_info, name='post_info'),
    path(r'post_result', views.receive_info, name='post_info_true'),
    path(r'login', views.login, name='login'),
    path(r'log_out', views.log_out, name='log_out'),
    path(r'login_handle', views.login_handle, name='login_handle')
]

视图
mysite/students/views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .models import ClassStudents


def post_info(request):
    uname = request.session.get('uname')
    context = {'content': uname}
    return render(request, 'students/post_info.html', context)

def login(request):
    return render(request, 'students/login.html')


def log_out(request):
    # request.session['uname'] = None
    # del request.session['uname']
    # request.session.clear()
    request.session.flush()
    return HttpResponseRedirect(reverse('students:post_info'))


def login_handle(request):
    uname = request.POST['uname']
    upwd = request.POST['upwd']
    q = ClassStudents.objects.filter(name=uname)
    if q.count() != 1:
        page_show = "数据库没有查询到信息,还未注册"
    else:
        students = q.first()
        stu_number = str(students.stu_number)
        if stu_number == upwd:
            request.session['uname'] = request.POST['uname']
            # request.session.set_expiry(10)
            # request.session.set_expiry(timedelta(days=5))
            request.session.set_expiry(0)
            # request.session.set_expiry(None)
            return HttpResponseRedirect(reverse('students:post_info'))
        else:
            page_show = "输入的密码有误"
    context = {'page_show': page_show}
    return render(request, 'students/post_info_result.html', context)

mysite/templates/students/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <form method="post" action="{% url 'students:login_handle' %}">
        {% csrf_token %}
     用户名:<input type="text" name="uname"/>  <br>
        密码:<input typepassword" name="upwd"/>  <br>
    <input type="submit" value="登录"/>  <br>
</form>
</head>
<body>

</body>
</html>

uname = request.session.get(‘uname’)
get(key, default=None):根据键获取会话的值
clear():清除所有会话
flush():删除当前的会话数据并删除会话的Cookie
del request.session[‘member_id’]:删除会话
会话过期时间
set_expiry(value):设置会话的超时时间
如果没有指定,则两个星期后过期
如果value是一个整数,会话将在values秒没有活动后过期
若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
如果value为None,那么会话永不过期

本文地址:https://blog.csdn.net/qq_22808061/article/details/107547231