Django-视图
概述
- 作用
- 接收Web请求并返回web响应
 
- 本质
- 就是一个Python函数,被定义在views.py文件中
 
- 响应
- 可以是一个网页的HTML内容、一个重定向、数据、一个404错误等等
 
- 过程
 ![过程图]() 
URLconf
- 
指定根级url配置文件- settings.py文件中的- ROOT_URLCONF
 
- 
指定子路由- 在应用下创建子路由urls.py文件
- 在主路由中引用1 
 2
 3
 4
 5urlpatterns = [ 
 url(r'^admin/', admin.site.urls),
 # namespace表示命名空间
 url(r'^', include('myApp.urls', namespace="sunck")),
 ]
 
- 
urlpatterns- 一个RegexURLResolver实例的列表
- url()参数- 正则表达式
- 视图函数
- 名称1 url(r'^$', views.index, name="index"), 
 
 
- 一个
视图函数
- 
定义视图- **本质:**一个函数
- 视图参数:
- 
一个 HTTPRequest对象
- 
通过正则表达式组获取的位置参数 如果路由带有正则表达式组,在定义视图函数时,要对应用形参接收 
- 
通过正则表达式组获取的关键字参数 
 
- 
- **位置:**应用目录下的views.py文件中
- **说明:**如果处理的功能过多,可以将视图定义在不同的py文件中
 
- 
错误视图- 
404- 在templates目录下创建名为404.html文件1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12<!DOCTYPE html> 
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>公益404</title>
 </head>
 <body>
 <script src="//qzonestyle.gtimg.cn/qzone/hybrid/app/404/search_children.js"
 charset="utf-8" homePageUrl="/" homePageName="返回首页">
 </script>
 </body>
 </html>
- 修改settions.py文件1 
 2
 3DEBUG = False 
 ALLOWED_HOSTS = ["*",]当为True时永远不会使用404页面 
 
- 在
- 
500- 在视图代码中出现运行时错误
 
- 
400- 错误来自客户端的操作
- 当用户进行的操作在安全方面可以的时候,例如篡改会话cookie
 
 
- 
HttpRequest对象
- 
概述: - 服务器收到http协议的请求后,会根据报文创建HTTPRequest对象
- 视图函数的第一个参数时HTTPRequest对象
 
- 
属性- **path:**字符串类型,表示请求的完整路径,不包含域名和端口
- **method:**字符串类型,表示使用的HTTP方法,常用的包括GET、POST
- **encoding:**字符串类型,表示提交数据的编码方式- 如果为None则表示使用浏览器默认的设置,一般为utf-8
- 这个属性是可写的,可以通过修改它来修改方法表单数据的编码
 
- **GET:**一个类似字典的对象,包含了get请求方式的所有参数
- **POST:**一个类似字典的对象,包含了POST请求方式的所有参数
- **FILES:**一个类似字典的对象,包含的是所有的上传文件
- **COOKIES:**一个标准的python字典,包含所有的cookie,键和值都是字符串
- **session:**一个即可读又可写的类似于字典的对象,表示当前会话,只有Django启动会话才支持session属性
 
- **
- 
方法- **is_ajax():**如果请求是通过XMLHttpRequest发起的,返回True
 
- **
- 
QueryDict对象- request对象的属性GET、POST都是QueryDict类型的对象
- 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
- get():- 功能:根据键获取值
- 注意:只能获取一个值;如果一个键同时用过多个值,获取最后一个值
 
- **getlist():**将键对应的值以列表的形式返回,可以获取一个键的多个值
 
- 
GET属性- 127.0.0.1:8000/get1?a=1&b=2&c=31 
 2
 3
 4
 5def get1(request): 
 a = request.GET.get("a")
 b = request.GET.get("b")
 c = request.GET.get("c")
 return HttpResponse(a + b + c)
- 127.0.0.1:8000/get2?a=1&a=2&c=31 
 2
 3
 4def get2(request): 
 alist = request.GET.getlist("a")
 c = request.GET.get("c")
 return HttpResponse(alist[0] + alist[1] + c)
 
- 127.0.0.1:8000/get1?a=1&b=2&c=3
- 
POST属性- 
使用表单提交,目前需要在settings.py中注释掉csrf 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>登陆</title>
 </head>
 <body>
 <form action="/login/" method="POST">
 {# {% csrf_token %}#}
 账号:<input type="text" value="" name="username"/><br/>
 密码:<input type="password" value="" name="passwd"/><br/>
 爱好:<input type="checkbox" value="power" name="hobby"/>权利
 <input type="checkbox" value="money" name="hobby"/>金钱
 <input type="checkbox" value="knowledge" name="hobby"/>知识<br/>
 <input type="submit" value="登陆"/>
 </form>
 </body>
 </html>1 
 2
 3
 4
 5
 6
 7
 8
 9def login(request): 
 if request.method == "GET":
 return render(request, "myApp/login.html")
 else:
 username = request.POST.get("username")
 passwd = request.POST.get("passwd")
 hobbys = request.POST.getlist("hobby")
 print(username, passwd, hobbys)
 return HttpResponse("收到用户信息")
 
- 
HttpResponse对象
- 
**概述:**HttpRequest对象是由Django自动创建,HTTPResponse对象由程序员创建 
- 
用法- 调用模板:render()函数- 原型:render(request, template_name, context=None)
- 说明:结合一个给定模板和一个给定的上下文字典,并返回一个渲染后的HTTPResponse对象
- 参数:
- request:用于生成- response
- template_name:要使用的模板名称
- context:传递个模板的数据
 
- 应用:return render(request, "myApp/login.html")
 
- 原型:
- 直接返回数据:return HttpResponse("收到用户信息")
 
- 调用模板:
- 
属性- **content:**表示返回的内容,字符串类型
- **charset:**表示response采用的编码字符集,字符串类型
- **status_code:**响应的HTTP状态码
- **content_type:**指定输出的MIME类型1 
 2
 3
 4
 5
 6
 7
 8def restest(request): 
 response = HttpResponse()
 response.content = "sunck is a nice man"
 response.charset = "utf-8"
 response.status_code = 200
 response.content_type = "application/json"
 return response
 
- **
- 
方法- **init:**使用页面内容实例化HTTPResonance对象
- write(content):以文本的方式写
- **flush():**以文件的方式输出缓冲区
- **set_cookie(key, value, max_age=None, expires=None):**设置cookie
- **dalete_cookie(key):**删除指定cookie,如果删除的cookie不存在就当什么都没发生
 
- **
- 
子类HttpResponseRedirect- 重定向,服务端跳转1 
 2
 3def index1(request): 
 # 路由重定向
 return HttpResponseRedirect('/')
- 简写方式:redirect()- 原型:redirect(to, *args, **kwargs)
- 实现:1 
 2
 3
 4def index1(request): 
 # 路由重定向
 # return HttpResponseRedirect('/')
 return redirect("/")
- 注意:to推荐使用反向解析
 
 
- 重定向,服务端跳转
- 
子类JsonResponse- 返回Json数据,一般用于ajax异步请求
- JsonResponse的对象的Content-Type值默认为application/json
 
状态保持
- 
概述: - http协议是无状态,每次请求都是一次新的请求,不会记得之前的通信状态
- 客户端与服务端的一次通信就是一次会话
- 实现状态保持的方式:在客户端或服务端存储会话的有关数据
- 存储方式:
- cookie
- session:会话一般指的是session对象
 
- 使用cookie,所有的数据存储在客户端,在客户端不要存储敏感信息
- 推荐使用session方式,所有的数据存储在服务端,在客户端cookie中存储session_id
- 状态保持的目的:在一段时间内跟踪请求者的状态,可以实现跨页面的访问请求者的数据
- 注意:不同的请求者之间不会共享数据,与请求者一一对应的
 
- 
启用session:settings.py文件- INSTALLED_APPS1 'django.contrib.sessions', 
- MIDDLEWARE1 'django.contrib.sessions.middleware.SessionMiddleware', 
 
- INSTALLED_APPS
- 
使用session- 启用会话后,每个HTTPRequest对象将具有一个session属性,它是一个类似字典的对象
- 取值:
- get(key, default=None)
- 根据键获取会话的值
 
- 删除:
- clear():清除所有会话
- flush():删除当前会话数据,并且删除cookie
- del request.session['键名']:删除一个会话
 
 
- 
示例1 
 2
 3
 4
 5# 状态保持 
 url(r'^home/$', views.home),
 url(r'^cart/$', views.cart),
 url(r'^login/$', views.login),
 url(r'^quit/$', views.quit),1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44from django.shortcuts import render, redirect 
 def home(request):
 username = request.session.get("username", default="未登录")
 return render(request, 'myApp/home.html', {"username": username})
 def cart(request):
 username = request.session.get("username", default="未登录")
 return render(request, 'myApp/cart.html', {"username": username})
 def login(request):
 if request.method == "GET":
 fromPath = request.GET.get("from")
 return render(request, 'myApp/login.html', {"from": fromPath})
 else:
 username = request.POST.get("username")
 passwd = request.POST.get("passwd")
 url = request.GET.get("from")
 if username == "sunck" and passwd == "123qweasdzxc":
 # 登陆验证成功
 # 将用户名存储到session中
 request.session["username"] = username
 url = "/" + url + "/"
 response = redirect(url)
 # 设置cookie
 response.set_cookie("token", "123456")
 return response
 else:
 # 登陆验证失败
 url = "/login/?from=" + url
 return redirect(url)
 from django.contrib.auth import logout
 def quit(request):
 logout(request)
 return redirect('/home/')1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>home</title>
 </head>
 <body>
 <h1>home欢迎:{{ username }}</h1>
 <a href="/login/?from=home">登陆</a>
 <a href="/quit/">退出</a>
 </body>
 </html>1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <title>登陆</title>
 </head>
 <body>
 <form action="/login/?from={{ from }}" method="POST">
 账号:<input type="text" value="" name="username" /><br/>
 密码:<input type="password" value="" name="passwd" /><br/>
 <input type="submit" value="登陆" />
 </form>
 </body>
 </html>
- 
过期时间- set_expiry(value):设置会话的过期时间
- 如果没有指定,则默认两个星期后过期
- 如果value是一个整数,会话会在value秒没有活动后过期
- 如果value是timedelta对象,会话将在当前时间加上这个指定的日期/时间后过期
- 如果value是0,那么用户会话的cookie将在用户的浏览器关闭时过期
- 如果value是None,那么会话永不过期1 
 2
 3
 4
 5
 6request.session["username"] = username 
 url = "/" + url +"/"
 response = redirect(url)
 # 设置过期时间
 request.session.set_expiry(10)
 
- 
存储session- 
基于数据库的会话:- 默认的会话存储方式1 SESSION_ENGINE='django.contrib.sessions.backends.db' 
 
- 默认的会话存储方式
- 
基于缓存的会话- 只存在本地内存中,如果丢失则不能找回,比数据库的方式读写更快1 SESSION_ENGINE='django.contrib.sessions.backends.cache' 
 
- 只存在本地内存中,如果丢失则不能找回,比数据库的方式读写更快
- 
缓存和数据库同时使用- 优先从本地缓存中获取,如果没有则从数据库中获取1 SESSION_ENGINE='django.contrib.sessions.backends.cached_db' 
 
- 优先从本地缓存中获取,如果没有则从数据库中获取
 
- 
- 
使用redis缓存session- 安装django-redis-session:pip install django-redis-sessions
- 配置:在settings.py最后边添加以上代码1 
 2
 3
 4
 5
 6SESSION_ENGINE = 'redis_sessions.session' 
 SESSION_REDIS_HOST = 'localhost'
 SESSION_REDIS_PORT = 6379
 SESSION_REDIS_DB = 0
 SESSION_REDIS_PASSWORD = ''
 SESSION_REDIS_PREFIX = 'session'
 
- 安装django-redis-session:
