1.视图简介

  作用:接受web请求,返回web响应

  本质:一个函数,定义在views.py文件中(定义在其他地方也行,约定俗成)

  流程:(如果匹配不到,报一个404错误)-----结果返回http response对象

1.1 视图配置

  在settings.py文件的ROOT_URLCONF部分指定根级url的配置(指向urls.py文件)

查找流程,mannage.py→settings.py→urls.py

习惯上,每个应用(APP)单独配置自己的urls.py,不写在根目录,防止因为应用过多,看起来太混乱不好维护,

配置自己的url:只需创建应用后在应用文件中创建urls.py文件(在根目录中包含)

1.2 简单的演示

根目录下的urls.py文件

from django.conf.urls import url, include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^booktest/', include('booktest.urls')),
] 

app目录下的url.py文件

from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^$',views.index),
]

views.py文件

from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse("Hello World!")

启动django

python manage.py runserver

访问网址

 

1.3 匹配规则

  第一步:去掉域名和端口号

  第二步:在根目录下匹配(匹配成功,进入include)

  第三步:去掉根目录里面已经匹配成功的,继续在APP中urls.py匹配(匹配成功,执行对应views.py中的函数)

  第四步:执行view.py中的函数

  匹配的时候,可以利用正则中的()可以保留匹配的内容,形如:(\d+)

1.4  urlconf 

#正则表达式非命名组,通过位置参数传递给视图
url(r'^([0-9]+)/$', views.detail, name='detail'), #正则表达式命名组,通过关键字参数传递给视图,本例中关键字参数为id
url(r'^(?P<id>[0-9]+)/$', views.detail, name='detail'),
  • 参数匹配规则:优先使用关键字(命名)参数,如果没有命名参数则使用位置参数
  • 每个捕获的参数都作为一个普通的python字符串传递给视图
  • 性能:urlpatterns中的每个正则表达式在第一次访问它们时被编译,这使得系统相当快
# namespace跟url里面的name一样,起名字用于反向解析
url(r'^', include('booktest.urls', namespace='booktest')),

1.5 反向解析(之后在写)

  • 如果在视图、模板中使用硬编码的链接,在urlconf发生改变时,维护是一件非常麻烦的事情
  • 解决:在做链接时,通过指向urlconf的名称,动态生成链接地址
  • 视图:使用django.core.urlresolvers.reverse()函数
  • 模板:使用url模板标签

2. 视图函数

2.1 基本视图

  调用,views内对应的函数即可,

2.2 错误视图(404未找到,500服务器未响应,400错误来自客户端)

  Django原生自带几个默认视图用于处理HTTP错误

  第一步:项目目录下,添加templates文件夹

  第二步:settings.py 中添加模板路径

  第三步:在templates中创建404.html(调试状态下,看不到这页面)

  settings.py 设置DEBUG为False

  设置允许谁请求主机

  

404.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>找不到,404</h1>
{{ request_path}}}
</body>
</html>

启动,错误的访问的结果为:

3. Reqeust对象(接收的对象)

  在django.http模块中定义了HttpRequest对象的API

3.1 属性

  下面除非特别说明,属性都是只读的

  path:一个字符串,表示请求的页面的完整路径,不包含域名

def index(request):
return HttpResponse(request.path)

  

  method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'

  encoding:一个字符串,表示提交的数据的编码方式

    如果为None则表示使用浏览器的默认设置,一般为utf-8

    这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值

  GET:一个类似于字典的对象,包含get请求方式的所有参数

  POST:一个类似于字典的对象,包含post请求方式的所有参数

  FILES:一个类似于字典的对象,包含所有的上传文件

  COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串

  session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见“状态保持”

  这些属性的用法类似

from django.http import HttpResponse
# Create your views here.
def index(request):
return HttpResponse(
# request.path,
# request.method,
# request.encoding,
request.GET,
# request.POST,
# request.FILES,
# request.COOKIES,
# request.session,
)

  

3.2  类似字典对象(QueryDict对象)

  字典:键值对,键不能相同

  QueryDict:键值对,键能相同,如果同一键有多个值,获取最后一个值

  get():根据键获取值,类字典

dict.get('键',default)
#或简写为
dict['键']

  getlist():根据键获取多个值

#将键的值以列表返回,可以获取一个键的多个值
dict.getlist('键',default)

3.3 GET属性 

  • QueryDict类型的对象
  • 包含get请求方式的所有参数
  • 与url请求地址中的参数对应,位于?后面
  • 参数的格式是键值对,如key1=value1
  • 多个参数之间,使用&连接,如key1=value1&key2=value2
  • 键是开发人员定下来的,值是可变的

对应三种视图getTest1用于定义链接,getTest2用于接收一键一值,getTest3用于接收一键多值

views.py

from django.shortcuts import render

# Create your views here.
# 展示链接的页面
def getTest1(request):
return render(request, 'booktest/getTest1.html') # 接收一键一值的情况
def getTest2(request):
# request.GET.get('a')
# 根据键接收值
a1 = request.GET['a']
b1 = request.GET['b']
c1 = request.GET['c']
# 构造上下文
context = {'a':a1,'b':b1,'c':c1}
# 向模板传递上下文,并渲染
return render(request, 'booktest/getTest2.html', context=context) # 接收一键多值的情况
def getTest3(request):
# 得到最后一个
a1 = request.GET['a']
# 得到多个
a2 = request.GET.getlist('a')
c1 = request.GET['c']
contest = {'a':a1,'a1':a2,'c':c1}
return render(request, 'booktest/getTest3.html',context=contest)

  

配置urls.py(APP里面的)

from django.conf.urls import url
from booktest import views
urlpatterns = [
url(r'^getTest1/$',views.getTest1),
url(r'^getTest2/$',views.getTest2),
url(r'^getTest3/$',views.getTest3),
]

  

配置模板

getTest1.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test1</title>
</head>
<body>
一键一值:<a href="/booktest/getTest2/?a=1&b=2&c=3">test2</a>
<hr>
一键多值:<a href="/booktest/getTest3/?a=1&a=2&c=3">test3</a>
</body>
</html>

  效果:

getTest2.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test2</title>
</head>
<body>
a:{{a}}
<hr>
b:{{b}}
<hr>
c:{{c}}
</body>
</html>

  效果

getTest3.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>test3</title>
</head>
<body>
a:{{a}}
<br>
a1:{{a1}}
<br>
a2:{%for item in a1 %}
{{ item }}
{% endfor %}
<br>
c:{{c}} </body>
</html>

  效果

3.4 POST属性

  • QueryDict类型的对象
  • 包含post请求方式的所有参数
  • 与form表单中的控件对应
  • 问:表单中哪些控件会被提交?
  • 答:控件要有name属性,则name属性的值为键,value属性的值为键,构成键值对提交
    • 对于checkbox控件,name属性一样为一组,当控件被选中后会被提交,存在一键多值的情况
  • 键是开发人员定下来的,值是可变的

使用表单提交,注释掉settings.py中的中间件crsf

 views.py

from django.shortcuts import render

# Create your views here.

# 提交表单
def postTest1(request):
return render(request,'booktest/postTest1.html')
# 展示提交的表单内容
def postTest2(request):
# 表单的name作为键,value作为值传递过来
uname = request.POST['uname']
upwd = request.POST['upwd']
ugender = request.POST['ugender']
uhobby = request.POST.getlist('uhobby')
context = {'uname': uname, 'upwd': upwd, 'ugender': ugender, 'uhobby': uhobby}
return render(request,'booktest/postTest2.html',context=context)

  

配置urls.py(APP里面的)

from django.conf.urls import url
from booktest import views
urlpatterns = [
# url(r'^getTest1/$',views.getTest1),
# url(r'^getTest2/$',views.getTest2),
# url(r'^getTest3/$',views.getTest3),
url(r'^postTest1/$',views.postTest1),
url(r'^postTest2/$',views.postTest2),
]

  

配置模板

postTest1.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>postTest1</title>
</head>
<body>
<form action="/booktest/postTest2/" method="post">
姓名:<input type="text" name="uname"/><br>
密码:<input type="password" name="upwd"/><br>
性别:<input type="radio" name="ugender" value="1"/>男
<input type="radio" name="ugender" value="0"/>女<br>
爱好:<input type="checkbox" name="uhobby" value="玩LOL"/>玩LOL
<input type="checkbox" name="uhobby" value="跳楼"/>跳楼
<input type="checkbox" name="uhobby" value="喝酒"/>喝酒
<input type="checkbox" name="uhobby" value="爬山"/>爬山<br>
<input type="submit" value="提交"/>
</form>
</body>
</html>

  效果:

postTest2.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>postTest2</title>
</head>
<body>
{{ uname }}<br>
{{ upwd }}<br>
{{ ugender }}<br>
{{ uhobby }}
</body>
</html>

  效果:

4. Response对象(发送的对象)

4.1 属性

  • content:表示返回的内容,字符串类型
  • charset:表示response采用的编码字符集,字符串类型
  • status_code:响应的HTTP响应状态码
  • content-type:指定输出的MIME类型(解析方式)

4.2 方法

  • init :使用页内容实例化HttpResponse对象
  • write(content):以文件的方式写
  • flush():以文件的方式输出缓存区
  • set_cookie(key, value='', max_age=None, expires=None):设置Cookie
    • key、value都是字符串类型
    • max_age是一个整数,表示在指定秒数后过期
    • expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期,注意datetime和timedelta值只有在使用PickleSerializer时才可序列化
    • max_age与expires二选一
    • 如果不指定过期时间,则两个星期后过期

views.py

from django.shortcuts import render
from django.http import HttpResponse
from datetime import * # Create your views here.
def cookieTest(request):
response = HttpResponse()
cookie = request.COOKIES
if 't1' in cookie:
response.write(cookie['t1'])
response.set_cookie('t1','abcaaa')
return response

urls.py

	url(r'^cookieTest/$',views.cookieTest),

  效果:

4.3 重定向

  一般作为:登录成功后,转向新的页面

  HttpResponseRedirect类继承于HttpResponse

views.py

from django.shortcuts import render,redirect
from django.http import HttpResponse,HttpResponseRedirect # Create your views here.
def redTest1(request):
# return HttpResponseRedirect('/booktest/redTest2/')
# 跟上面功能一致,也用于重定向(简写)
return redirect('/booktest/redTest2/')
# 转向来的页面
def redTest2(request):
return HttpResponse("这是转向来的页面")

urls.py

	url(r'^redTest1/$',views.redTest1),
url(r'^redTest2/$',views.redTest2),

 效果:访问:http://127.0.0.1:8000/booktest/redTest1/

 自动跳转,效果

4.4 状态保持

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

Django默认就启用Session,不用就去settings.py中禁用

使用Session(会存到数据库中去)

  • 启用会话后,每个HttpRequest对象将具有一个session属性,它是一个类字典对象
  • get(key, default=None):根据键获取会话的值
  • clear():清除所有会话
  • flush():删除当前的会话数据并删除会话的Cookie
  • del request.session['member_id']:删除会话

views.py

from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect # Create your views here.
# 第一个登录显示页面
def session1(request):
# 键不存在,设置默认值
uname = request.session.get('myname','未登录')
context = {'uname': uname}
return render(request, 'booktest/session1.html', context=context) # 登录表单提交阶段
def session2(request):
return render(request, 'booktest/session2.html') # 删除session,退出
def session3(request):
del request.session['myname']
return redirect('/booktest/session1/') def session2_handle(request):
uname = request.POST['uname']
# session对象(字典) 往session对象中写对象
request.session['myname'] = uname
# 重定向,显示登录的页面
return redirect('/booktest/session1/')

urls.py

	url(r'^session1/$',views.session1),
url(r'^session2/$',views.session2),
url(r'^session2_handle/$',views.session2_handle),
url(r'^session3/$',views.session3),

  

session1.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>login</title>
</head>
<body>
<h1>你好:{{ uname }}</h1>
<br>
<a href="/booktest/session2/">登录</a>
<br>
<a href="/booktest/session3/">退出</a>
</body>
</html>

  效果:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>表单</title>
</head>
<body>
<form action="/booktest/session2_handle/" method="post">
<input type="text" name="uname">
<input type="submit" name="登录">
</form>
</body>
</html>

 效果:

 

因为Session需要存到数据库:需要进行数据迁移-------这个需要运行前先迁移

settings.py(可以用已经迁移过的数据库、表)

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'test2',
'USER':'root',
'PASSWORD':'',
'HOST':'localhost',
'POST':'3306',
}
}

  

提交表单后效果

点击退出后的效果(使用默认值,清楚session)

4.5 会话

会话过期时间

  • set_expiry(value):设置会话的超时时间
  • 如果没有指定,则两个星期后过期
  • 如果value是一个整数,会话将在values秒没有活动后过期
  • 若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
  • 如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
  • 如果value为None,那么会话永不过期
  • 修改视图中session2_handle函数,查看效果
def session2_handle(request):
uname = request.POST['uname']
# session对象(字典) 往session对象中写对象
request.session['myname'] = uname
# 设置会话过期时间
request.session.set_expiry(0)
# 重定向,显示登录的页面
return redirect('/booktest/session1/')  

存储session

数据库中的session

base64解码--session_data

  • 使用存储会话的方式,可以使用settings.py的SESSION_ENGINE项指定
  • 基于数据库的会话:这是django默认的会话存储方式,需要添加django.contrib.sessions到的INSTALLED_APPS设置中,运行manage.py migrate在数据库中安装会话表,可显示指定为
SESSION_ENGINE='django.contrib.sessions.backends.db'

  存在缓存

SESSION_ENGINE='django.contrib.sessions.backends.cache'

  存在数据库+缓存

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

流程

<Django> MVT三大块之view(视图)的更多相关文章

  1. <Django> MVT三大块之Template(模板)

    1.模板简介 创建项目,基本配置 第一步:配置数据库 第二步:创建APP,配置APP 第三步:配置模板路径 第四步:配置分发urls.py(APP里面的) 根目录下,增加命名空间namespace,作 ...

  2. <Django> MVT三大块之Models(模型)

    1.ORM(对象-关系-映射)---面向对象,不需要面向SQL语句 根据对象的类型生成表结构 将对象.列表的操作,转化成SQL语句 将SQL语句查询的结果转化成对象.列表 目的:实现数据模型与数据库的 ...

  3. Django基础三之路由、视图、模板

    Django基础三之路由.视图.模板 目录 Django基础三之路由.视图.模板 1. Django 请求和返回周期 1.1 路由层之路由匹配 1.2 有名分组 1.3 无名分组 2. 反射解析 3. ...

  4. day052 django第三天 url和视图

    一.基本格式 from django.conf.urls import url from . import views #循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数 ...

  5. Django的View(视图)和路由系统

    一.Django的View(视图) 1.介绍 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一 ...

  6. Django框架 之 view视图

    Django框架 之 view视图 浏览目录 概述 简单的视图 HttpRequest对象 CBV和FBV 给视图加装饰器 Request对象 Response对象 JsonResponse对象 Dj ...

  7. django 第三天 视图

    今日内容 一.url路由分发之include 项目文件夹下的urls.py文件中的url写法: from django.conf.urls import url,include from django ...

  8. day 53-1 Django基础三之视图函数

    Django基础三之视图函数   本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...

  9. day 67 Django基础三之视图函数

    Django基础三之视图函数   本节目录 一 Django的视图函数view 二 CBV和FBV 三 使用Mixin 四 给视图加装饰器 五 Request对象 六 Response对象 一 Dja ...

随机推荐

  1. 单源最短路径问题2 (Dijkstra算法)

    用邻接矩阵 /* 单源最短路径问题2 (Dijkstra算法) 样例: 5 7 0 1 3 0 3 7 1 2 4 1 3 2 2 3 5 2 4 6 3 4 4 输出: [0, 3, 7, 5, 9 ...

  2. 视频质量评测标准——VMAF

    阿里云视频云直播转码每天都会处理大量的不同场景.不同编码格式的直播流.为了保证高画质,团队借助VMAF标准来对每路转码的效果做质量评估,然后进行反馈.调优.迭代.这么做的原因在于,像动作片.纪录片.动 ...

  3. DELPHI读取网页源文件和获取字符串

    说到网页采集,通常大家以为到网上偷数据,然后把到收集到的数据挂到自己网上去.其实也可以将采集到的数据做为公司的参考,或把收集的数据跟自己公司的业务做对比等.目前网页采集多为3P代码为多(3P即ASP. ...

  4. 常用Git命令以及出现的状况ing

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 我的GitHub: Cwolf9 下面是我学习Git时了解到的一些命令和状况经验. 把它们记下来免得忘了.就算忘了也有地方看... 状 ...

  5. Web 开发规范 — WSGI

    目录 目录 WSGI 简介 为什么需要 WSGI 这个规范 WSGI 如何工作 WSGI的角色 Server 如何调用 Application application 的两个参数 applicatio ...

  6. [转]WinForm DataGridView 绑定泛型List(List<T>)/ArrayList不显示的原因和解决

    背景:无意间遇到了一个不大不小的问题,希望对一些遇到的人有所帮助! 一.问题 WinForm DataGridView 绑定泛型List (List<T>)/ArrayList不显示,UI ...

  7. jquery scrollTop() 方法

    原文地址:http://www.w3school.com.cn/jquery/css_scrolltop.asp 实例 设置 元素中滚动条的垂直偏移: $(".btn1").cli ...

  8. 简单实用的makefile

    简单的makefile 为了说明问题,就新建一组文件如下: 文件布局及运行结果: make clean 按目录归置 文件看起来是是清楚了,但是makefile写得揪心. 实用版 (1)Makefile ...

  9. 搞懂这7个Maven问题,带你吊打面试官!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 作者:张丰哲 www.jianshu.com/p/20b39ab6a88c 在如今的互联网项目开发当中,特别是Java领域, ...

  10. Maven如何发布jar包到Nexus私库

    Nexus2可以通过管理界面来上传jar包到私库中,而最新的Nexus3却找不到了上传界面,只能通过以下方式来发布到私库. 发布第三方jar包 这种情况是maven远程仓库没有,本地有的第三方jar包 ...