06-Django视图
什么是视图?
视图就是应用中views.py文件中的函数,视图函数的第一个参数必须是request(HttpRequest)对象。返回的时候必须返回一个HttpResponse对象或子对象(包含HttpResponse)作为响应。子对象(render,redirect)。返回子对象预先接收HttpRequest,进行逻辑处理,返回web响应HttpResponse给请求者。(响应内容HTML内容,404错误,重定向,json数据)
使用视图时的两个步骤:
1、配置URLconf即配置路由
2、在应用中的views.py中定义视图
项目准备:
创建项目-----创建应用------安装应用(设置里面的INSTALL__APPS)-----配置模板路径-----本地化(语言,时区)------mysql数据库(配置导入包,替换项目自带的数据库)------URLconfig------视图
mysql数据库使用之前的bookdb:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
'NAME': 'bookdb', # 数据库名称
'HOST': 'localhost', # 数据库主机(建议使用主机真实IP)
'PORT': '', # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': '', # 数据库密码
}
}
项目准备好后,测试逻辑。即随便写个路由然后到视图函数随便返回一个字符串,如果返回到浏览器,说明项目逻辑OK。
URL配置
开发者通过在浏览器的地址范围输入网址请求网站,对于Django开发的网站,由哪一个视图进行处理请求,是由网址匹配找到的
配置URLconf
1.在setings.py中去看指定网址配置是否正确。
ROOT_URLCONF = "项目名字.urls"
2、项目中的urls.py
匹配成功后,包含到应用的urls.py(现在的新版本不用关注这里啦,如果版本低,那么出问题需要知道)
url(正则,include(应用.urls))
3、应用中的urls.py
匹配成功后,调用对应的views.py
#这是常规匹配
path('admin/', admin.site.urls),
re_path("^$",views.index),
#下面这个是正则匹配
URL中取值
如果想从url中获取值,需要在正则表达式中使用分组。
获取值的两种方式:
1、位置参数(参数的位置不能错)
2、关键字参数
注意:两种参数不能混合使用,在一个正则表达式中只能使用一种参数形式
位置参数
例如用上面两种方式获取URL值,提出188和545121 http://127.0.0.1:8000/188/545121/
1、应用中的urls.py
re_path("^(\d+)/(\d+)/$",views.index),
2、views.py:
#位置参数的应用
def index(request,num1,num2):
#构造上下文
content = {"num1":num1,"num2":num2}
return render(request,"Book/index.html",content)
3、模板中的代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>位置参数</title>
</head>
<body>
<ur>
<li>{{ num1 }}</li>
<li>{{ num2 }}</li>
</ur>
</body>
</html>
关键字参数
1、应用中的urls.py
其中?P<name>的部分表示为这个参数的名称为(name)(自定义名称)
#关键字参数
re_path("^(?P<number1>\d+)/(?P<number2>\d+)/$",views.index),
2、views.py
#关键字参数的应用
def index(request,number2,number1):
#构造上下文
content = {"number2":number2,"number1":number1}
return render(request,"Book/index.html",content)
3、模板代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>关键字参数</title>
</head>
<body>
<ur>
<li>{{ number2 }}</li>
<li>{{ number1 }}</li>
</ur>
</body>
</html>
从结果可以看出,两个位置变化了,说明给参数别明名了,名字的位置不同,参数的位置也跟着变化。
错误视图
Django内置处理HTTP错误的视图,主要错误及视图包括
- 404错误:找不到页面视图
- url匹配不成功会发生404错误
- 400错误:错误的请求视图
- 来自客户端的安全方面非法操作会引发400错误
- 500错误:服务器错误视图
- 在视图中代码运行报错会发生500错误
只需要在模板中定义指定html文件即可,不需要配置URLconf和准备视图,但是要配置模板加载路径
404.html
400.html
500.html
- ...
创建404模板:创建在
templates
文件夹下定义404模板内容
如果想看到错误视图而不是调试信息,需要修改
settings.py
文件的DEBUG
项展示404模板效果
HttpRequest对象
服务器接收到HTTP协议的请求后,会根据报文创建HttpRequest对象,这个HttpRequest对象,是由Django封装好的,专门接收客户端发送的消息。HttpRequest对象属性几乎都是读取内容的。
常见属性
path:一个字符串,表示请求的页面的完整路径,不包含域名
method:一个字符串,表示请求使用的HTTP方法,常用值包括:GET、POST
在浏览器中给出地址发出请求采用get方式,如超链接
在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求
GET:一个类似于字典的QueryDict对象
包含get请求方式的所有参数,?后面的内容
POST:一个类似于字典的QueryDict对象
包含post请求方式的所有参数
FILES:一个类似于字典的QueryDict对象,包含所有的上传文件
COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串
encoding:一个字符串,表示提交的数据的编码方式
如果为None则表示使用浏览器的默认设置,一般为utf-8
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值
session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见“状态保持”
获取属性
配置URLconf
http://127.0.0.1:8000/test/
path('test/', views.test),
2、views.py
def test(request):
#获取属性,构造上下文
content = {"path":request.path,"method":request.method,"GET":request.GET}
return render(request,"Book/test.html",content)
3、模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>
<ul>
<span>路径:</span><li>{{ path }}</li>
<span>请求方法:</span><li>{{ method }}</li>
<span>GET属性:</span><li>{{ GET }}</li>
</ul>
</body>
</html>
结果:
QueryDict对象
QueryDict类型的对象不是字典,仅仅是类似字典的对象而已。
相关方法
get()方法:根据键获取值,如果一个键同时拥有多个值将获取最后一个值
如果键不存在则返回None值,可以设置默认值进行后续处理 dict.get('键',默认值)
可简写为
dict['键']
getlist()方法:根据键获取值,值以列表返回,可以获取指定键的所有值,如果键不存在则返回空列表[],可以设置默认值进行后续处理 dict.getlist('键',默认值)
GET属性
HttpRequest对象的GET属性,返回一个类似于字典的QueryDict对象,对象中包含GET请求的所有请求参数。
根据键取值:get(),getlist()
分析:
get请求时url格式,在请求地址末尾使用?,之后以“”键=值“”的格式拼接,多个键值之间以&链接
获取请求参数(http://127.0.0.1:8000/index/?a=10&b=20&c=python
)
# QueryDict类型的对象dict
dict = request.GET a = dict.get('a')
b = dict.get('b')
c = dict.get('c')
获取请求参数一键多值情况(http://127.0.0.1:8000/get/?a=10&b=20&a=python
)
# QueryDict类型的对象dict
dict = request.GET # a = dict.get('a') # 返回最后一个值
a = dict.getlist('a') # 返回所有值
b = dict.get('b')
POST属性
使用form表单提交请求时,method方式为post则会发送post请求。(1、需要使用HttpRequest对象的POST属性接收参数,POST属性返回QueryDict类型的对象)
备注:checkbox多选项,name属性的值相同为一组,被选中的项会被提交,出现一键多值情况。
配置URLconf(测试post)
path('test/', views.test),
视图
def test(request):
if request.method == "GET":
#获取属性,构造上下文
content = {"path":request.path,"method":request.method,"GET":request.GET}
return render(request,"Book/test.html",content)
else:
dict = request.POST
uname = dict.get('uname')
upassword = dict.get('upassword')
sex = dict.get('sex')
like = dict.getlist('like') # 一键多值 content = {'uname': uname, 'upassword': upassword, 'sex': sex, 'like': like}
return render(request, 'Book/test.html', content)
模板
<form action="/post1/" method="post"> {# Django项目默认会做CSRF安全验证 #}
{% csrf_token %} <input type="text" name="uname">
<br>
<br>
<input type="password" name="upassword">
<br>
<br>
<input type="radio" name="sex" value="男">男 <input type="radio" name="sex" value="女">女
<br>
<br>
<input type="checkbox" name="like" value="足球">足球 <input type="checkbox" name="like" value="篮球">篮球 <input type="checkbox" name="like" value="羽毛球">羽毛球
<br>
<br>
<input type="submit" value="提交">
</form>
从上面可以看出浏览器第二次接收到服务器的响应数据
HttpResponse对象
视图在接受请求并处理后,必须返回HttpResponse对象,或子对象。
常见属性
content:表示返回的内容
charset:表示response采用的编码字符集,默认为utf-8
status_code:返回的HTTP响应状态码
content_type:指定返回数据的的MIME类型,默认为'text/html'
常见方法
init:创建HttpResponse对象后完成返回内容的初始化
write:向响应体中写数据
set_cookie:设置Cookie信息 set_cookie('key', 'value', max_age=None, expires=None)
cookie是网站以键值对格式存储在浏览器中的一段纯文本信息,用于实现用户跟踪
max_age是一个整数,表示在指定秒数后过期
expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期
max_age与expires二选一
如果不指定过期时间,默认两个星期后过期
delete_cookie:删除指定的key的Cookie,如果key不存在则什么也不发生 delete_cookie('key')
HttpResponse响应内容示例
1、直接响应数据
return HttpResponse(“OK”)
2、调用模板-简写
from django.shortcuts import render def test(request):
# 定义上下文
content= {'key':'value'}
# 获取模板,渲染模板,让模板语言执行
return render(request, 'Book/test.html', content)
JsonResponse
继承Httpresponse,被定义在django.http模块中。(接收字典作为参数)
使用场景:
当需要响应json数据给请求者时,需要用到JsonResponse。
他的content-type默认为application/json,响应json格式。
案例:ajax实现网页局部刷新需要使用到JsonResponse响应的json数据
备注:为了更方便,可以利用python中的json模块,序列化数据,在js代码中反序列化数据,也可以实现json数据的传输。
需求实现
1.准备URLconf,视图,模板
2.导入 jquery 静态文件
3.发起ajax请求
4.响应json字典
5.处理json字典,构造html内容
1、准备URLconf,视图,模板
#ajax请求
path('ajax/', views.ajax),
#ajax请求
def ajax(request):
return render(request,"Book/ajax.html")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
</head>
<body>
<input type="button" id="ajaxbtn" value="ajax_request">
<ul>
<li>啦啦</li>
<li>你你你</li>
<li>我我我</li>
<li>他他他</li> </ul> <ul id="test" style="background: red;width: 100px;height: 100px;">
<li>你好呀</li>
<li>我好呀</li>
<li>他好呀</li>
<li>哈呀好呀</li> </ul> </body>
</html>
2、导入jquery静态文件
<head>
<meta charset="UTF-8">
<title>Ajax</title>
{#导入jquery文件#}
<script src="/static/js/jquery-3.4.1.min.js"></script>
</head>
配置静态文件加载路径
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR,"static")
]
静态文件加载成功!
3、发起ajax请求
{#ajax请求json数据#}
<script>
$(function () {
//获取ajaxbtn按钮点击事件
$("#ajaxbtn").click(function () {
//ajax请求,参数一:请求地址;参数2:请求回调,response表示请求响应的字典
$.get("/jsondata/",function (response) {
alert("收到响应啦");
}); }); });
</script>
4、响应json字典
准备模型类:
#创建书籍信息
class Books(models.Model):
name = models.CharField(max_length=20)#书名
pub_data = models.DateField(null=True)#出版日期
#参数max_digits表示总位数 参数decimal_places表示小数位数
price = models.DecimalField(max_digits=8,decimal_places=2)#价格
publish = models.CharField(max_length=20)
#外键 将字段定义在多的一端中 级联删除
author = models.ForeignKey(Authors,on_delete=models.CASCADE)
#修改表名(元类)
class Meta:
db_table = "books" def __str__(self):
return self.name
#创建作者信息表
class Authors(models.Model):
name = models.CharField(max_length=20)#作者名字
gender = models.BooleanField(default=True)#性别
age = models.IntegerField()#年龄
addr = models.CharField(max_length=60)
tel = models.IntegerField()
#元类修改表名
class Meta:
db_table = "authors"
def __str__(self):
return self.name
构造json字典分析
“”“
原始:book = [book0,book1,book2,book3]
结果:response = {"booklist":[{"name":"大局观"},{"name":"与时间做朋友"},{"name":"稀缺"},{"name":"怎样解题"}]} ”“”
实现
def jsondata(request):
#查询所有书籍
books = Books.objects.all()
#构造书籍字典
list1 = []
for book in books:
list1.append({"name":book.name})
#构造json字典
jsondict = {"booklist":list1}
return JsonResponse(jsondict)
5、处理字典,构造html内容
{#ajax请求json数据#}
<script>
$(function () {
//获取ajaxbtn按钮点击事件
$("#ajaxbtn").click(function () {
//ajax请求,参数一:请求地址;参数2:请求回调,response表示请求响应的字典
$.get("/jsondata/",function (response) {
//删除id="test"的ul里面的li
$("#test li").remove();
//获取jsondict字典里面的书籍列表信息
booklist = response.booklist;
//获取id="test"的url
test_ul = $("#test");
//遍历书籍列表信息,拼接li
$.each(booklist,function (i,book) {
test_ul.append("<li>"+book.name+"</li>");
});
}); }); });
</script>
HttpResponseRedirect(redirect和这个用法相同)
当一个逻辑处理完成后,不需要向客户端呈现数据,而是转回到其它页面
如添加成功、修改成功、删除成功后显示数据列表,而数据的列表视图已经开发完成,此时不需要重新编写列表的代码,而是转到这个视图就可以
从一个视图转到另外一个视图,就称为重定向
Django中提供了HttpResponseRedirect对象实现重定向功能
这个类继承自HttpResponse,被定义在django.http模块中
from django.shortcuts import render, redirect
from django.http import HttpResponse,JsonResponse,HttpResponseRedirect
返回的状态码为302
重定向示例
需求:每次登陆网页成功后都需要跳转到新的页面。
实现:
配置URLconf
path('login/', views.login),
视图
def login(request):
#处理登陆逻辑完,跳转页面
return redirect("http:www.baidu.com")
状态保持
浏览器请求服务器是无状态的。
无状态:指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。
无状态原因:浏览器与服务器是使用Socket套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的Socket连接,而且服务器也会在处理页面完毕之后销毁页面对象。
有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等
实现状态保持主要有两种方式:
在客户端存储信息使用Cookie
在服务器端存储信息使用Session
Cookie
- Cookie:指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地的数据(通常经过加密)。
- 复数形式Cookies。
- Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。
- Cookie是由服务器端生成,发送给客户端浏览器,浏览器会将Cookie的key/value保存,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。
- Cookie的key/value可以由服务器端自己定义。
- 应用:
- 最典型的应用是判定注册用户是否已经登录网站,用户可能会得到提示,是否在下一次进入此网站时保留用户信息以便简化登录手续,这些都是Cookie的功用。
- 网站的广告推送,经常遇到访问某个网站时,会弹出小窗口,展示我们曾经在购物网站上看过的商品信息。
- 购物车,用户可能会在一段时间内在同一家网站的不同页面中选择不同的商品,这些信息都会写入Cookie,以便在最后付款时提取信息。
提示:
- Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用
- Cookie基于域名安全,不同域名的Cookie是不能互相访问的(比如我访问百度和淘宝使用的是不同的cookie)
当浏览器请求某网站时,会将本网站下所有Cookie信息提交给服务器,所以在request中可以读取Cookie信息
Cookie使用
1、设置cookie
response.set_cookie("lishuntao","hello")
2、读取cookie
read_cookie = request.COOKIES["lishuntao"]
3、判断是否存在某个Cookie
if request.COOKIES.has_key("lishuntao"):
pass
4、删除Cookie
response.delete_cookie("lishuntao")
Session
- 对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息
- 在服务器端进行状态保持的方案就是
Session
- Session依赖于Cookie
启用Session
Django项目默认启用Session(禁用Session:将Session中间件注释即可)
Session存储方式
Session数据,可以存储在数据库、缓存、Redis等(设置SESSION_ENGINE项指定Session存储方式)
存储在数据库中,默认储存方式。
储存在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
混合存储:优先从本机内容中存取,如果没有则从数据库中存取
如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用
默认存储Session的数据库
迁移后会在数据库中创建出存储Session的表
表结构
由表结构可知,操作Session包括三个数据:键,值,过期时间
常见Session操作
1、设置session
request.session["key"]=value
2、读取session
request.session.get("key",default)
3、删除指定键的值,在存储中只删除某个键对应的值
del request.session["key"]
4、清除所有键的值,在存储中删除所有键对应的值
request.session.clear()
5、清除session数据,在存储中删除所有键值,变成空表
request.session.flush()
6、设置会话的超时时间
request.session.set_expiry(value)
#如果value是一个整数,会话将在value秒没有活动后过期
#如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
#如果value为None,那么会话则两个星期后过期
Session依赖于Cookie
在使用Session后,会在Cookie中存储一个sessionid
的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid
后,会根据这个值找出这个请求者的Session
备注
1. 如果想使用Session,浏览器必须支持Cookie,否则就无法使用Session了
2. 存储Session时,键与Cookie中的`sessionid`相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置
06-Django视图的更多相关文章
- Django 2.0 学习(07):Django 视图(进阶-续)
接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...
- Django 06 Django模型基础1(ORM简介、数据库连接配置、模型的创建与映射、数据的增删改查)
Django 06 Django模型基础1(ORM简介.数据库连接配置.模型的创建与映射.数据的增删改查) 一.ORM系统 #django模型映射关系 #模型类-----数据表 #类属性-----表字 ...
- [diango]理解django视图工作原理
前言:正确理解django视图view,模型model,模板的概念及其之间的关联关系,才能快速学习并上手使用django制作网页 本文主要讲解自己在学习django后对视图view的理解 在进入正文之 ...
- Django 2.0 学习(03):Django视图和URL(下)
接上篇博文,继续分析Django基本流程. 编写第一个(view)视图函数 1.打开文件polls/views.py,输入下面的Python代码: from django.http import Ht ...
- 如何在django视图中使用asyncio(协程)和ThreadPoolExecutor(多线程)
Django视图函数执行,不在主线程中,直接 loop = asyncio.new_event_loop() # 更不能loop = asyncio.get_event_loop() 会触发 Runt ...
- Django 视图系统
Django 视图系统 概念 一个视图函数,简称视图,是一个简单的Python函数,用于接受Web请求并返回Web响应. 通常将视图函数写在project或app目录中的名为views.py文件中 简 ...
- 令Django 视图有默认 login_required
方法一 from django.template import RequestContext from django.shortcuts import render_to_response from ...
- 06: Django Admin
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- Django视图层之路由配置系统(urls)
视图层之路由配置系统(urls) URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于这个U ...
- 1.2、Django 视图与网址__进阶
Django 视图与网址进阶 1.1.简单使用: 把我们新定义的app加到settings.py中的INSTALL_APPS中 修改 HelloDjango/HelloDjango/settings. ...
随机推荐
- 数据结构导论 四 线性表的顺序存储VS链式存储
前几章已经介绍到了顺序存储.链式存储 顺序存储:初始化.插入.删除.定位 链式存储:初始化.插入.删除.定位 顺序存储:初始化 strudt student{ int ID://ID char nam ...
- SSH的 Write failed: Broken pipe 问题
问题现象: 表示连接管道已经断开 解决方法: 方法一:客户端配置 在客户端的 ~/.ssh/ config文件(如不存在请自行创建)中添加下面内容: ServerAliveInterval 60 方法 ...
- center----Iframe 用法的详细讲解
把iframe解释成“浏览器中的浏览器“很是恰当 <iframe frameborder=0 width=170 height=100 marginheight=0 marginwidth=0 ...
- Objective-C中 #include 和 #import 的区别
由于 Objective-C 兼容 C 语言,所以导入文件时, 可以使用 #include,也可以使用 #import (Objective-C 新增的) 如: #include <stdio. ...
- pytorch 中改变tensor维度的几种操作
具体示例如下,注意观察维度的变化 #coding=utf-8 import torch """改变tensor的形状的四种不同变化形式""" ...
- 埃氏筛法(求n以内有哪些个质数)
核心思想:从i=2开始,划去i的倍数,即剩下i为质数(如删去2的倍数后2为质数,再删去3的倍数后3为质数,4被删除则跳过,5未被删除则记录然后删除5的倍数...以此类推) #include <b ...
- Implement Property Value Validation in Code 在代码中实现属性值验证(XPO)
This lesson explains how to set rules for business classes and their properties. These rules are val ...
- Python Web(二)
Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.Django-debug-toolbar django-debug-toolbar 是一组可配置的面板,可显示 ...
- JS 实现
JavaScript 使用 HTML 中的脚本必须位于<script> 与 </script>标签之间. 脚本可被放置在 HTML 页面的 <body>和 < ...
- MySQL 事务提交 --不良好的事务习惯。
MySQL 事务提交 --不良好的事务习惯 我们知道"事务"是数据库区别于文件系统的重要特性之一.MySQL的InnoDB引擎中的事务也完全符合ACID(原子性 一致性 隔离性 持 ...