Django之深入了解视图层
视图层三板斧
规定视图函数必须有一个返回值,
并且返回值的数据类型必须是 HttpResponse 对象
HttpResponse
返回浏览器一个字符串
render
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
redirect
默认返回一个临时的重定向;传递permanent=True
可以返回一个永久的重定向。
扩展阅读:
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。
A页面临时重定向到B页面,那搜索引擎收录的就是A页面。
A页面永久重定向到B页面,那搜索引擎收录的就是B页面。
JsonResponse
前提知识点:前后端数据要交互,通常情况下采用json的字符串,后端需要写好响应的url接口并返回json格式的字符串,前端在访问你这个接口就行了。
前后端json 序列化和反序列化的方法
方法 | 后端 | 前端 |
---|---|---|
序列化 | json.dumps | JSON.stringfy |
反序列化 | json.loads | JSON.parse |
django非常友好,帮我们想到了这个问题,就有现成的对象来自动转成json的对象---JsonResponse
# 导入JsonResponse 对象
from django.http import JsonResponse
def index(request):
user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'}
# json数据序列化的时候,如果这个字典里有中文,
# 那么序列化的时候就不能序列化中文了,需要加参数ensure_ascii=False
return HttpResponse(json.dumps(user_dict,ensure_ascii=False))
# 同样django帮你想到了这点,直接用jsonresponse对象返回就行了,不需要导入json模块了。
# 但是同样也是不支持中文的,需要加参数json_dumps_params={'ensure_ascii':False}
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
L = [1,2,3,4]
# json默认是序列化字典用的,如果序列化其他数据类型的话会报错:
# In order to allow non-dict objects to be serialized set the safe parameter to False.
# 提示必须要加safe参数
return JsonResponse(L,safe=False)
FBV
基于函数版的视图任务
def index(request):
user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'}
# json数据序列化的时候,如果这个字典里有中文,
# 那么序列化的时候就不能序列化中文了,需要加参数ensure_ascii=False
return HttpResponse(json.dumps(user_dict,ensure_ascii=False))
# 同样django帮你想到了这点,直接用jsonresponse对象返回就行了,不需要导入json模块了。
# 但是同样也是不支持中文的,需要加参数json_dumps_params={'ensure_ascii':False}
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
L = [1,2,3,4]
# json默认是序列化字典用的,如果序列化其他数据类型的话会报错:
# In order to allow non-dict objects to be serialized set the safe parameter to False.
# 提示必须要加safe参数
return JsonResponse(L,safe=False)
然后在urls.py 路由匹配中写匹配规则
url(r'^index/', views.index)
CBV
基于类版的视图任务
# 导入View,继承View类
from django.views import View
class MyLogin(View):
def get(self,request):
print("我是MyLog里面的get方法")
return render(request,'login.html')
def post(self,request):
print("我是MyLog里面的post方法")
return HttpResponse("post")
然后在urls.py 路由匹配中写匹配规则,CBV书写方式有所不同
url(r'^login/', views.MyLogin.as_view())
# 通过看源码的执行流程:
# 访问类的属性和方法,方法加括号,执行优先级最高
# 项目一启动 会自动执行as_views方法
# 第一步 会 变形为 views.view
# url(r'login/',views.view),
# 然后进入view函数 --> self.dispatch(request, *args, **kwargs) --> if request.method.lower() in self.http_method_names:
# handler = getattr(self, request.method.lower(), self.http_method_not_allowed) --> return handler(request, *args, **kwargs)
CBV源码
我们通过看CBV执行的流程源码看出来,可以思考一个问题,
我们在视图中定义两个方法,get、post
为什么能够根据请求方式的不同,自动执行不同的方法?
django CBV方式执行源码重要部分:
路由层通过匹配
url(r'^login/', views.MyLogin.as_view())
首先遇到类名加括号,执行优先级最高,通过调用as_view得到一个返回值view,把它变形,
url(r'login/',views.view)
然后执行view的方法,会到dispatch方法中执行
判断请求的方式是什么,在不在事先定义好的方法列表里面
然后利用反射得到对请求方式的对象,再次return出去,执行请求方式对象里的内容.
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
...
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)
...
update_wrapper(view, cls.dispatch, assigned=())
return view
def dispatch(self, request, *args, **kwargs):
# 这里判断请求的方式是什么,在不在事先定义好的方法列表里面
# http_method_names = ['get',
# 'post',
# 'put',
# 'patch',
# 'delete',
# 'head',
# 'options',
# 'trace']
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
如何给FBV和CBV加装饰器
FBV加装饰器的方式很简单,和之前我们加装饰器没有区别。
# 定义一个计算执行时间的装饰器
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print('执行时间:',end_time - start_time)
return res
return inner
# 普通函数加装饰器
@outter
def index(request):
user_dict = {'username':'qinyj','age':18,'hobby':'独角兽的好事'}
# return HttpResponse(json.dumps(user_dict,ensure_ascii=False))
# json数据序列化的时候,如果这个字典里有中文,
# 那么序列化的时候就不能序列化中文了,需要加参数ensure_ascii=False
# 同样django帮你想到了这点,直接用jsonresponse对象返回就行了,不需要导入json模块了。
# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
L = [1,2,3,4]
# json默认是序列化字典用的,如果序列化其他数据类型的话会报错:
# In order to allow non-dict objects to be serialized set the safe parameter to False.
# 提示必须要加safe参数
return JsonResponse(L,safe=False)
那么CBV加加装饰器如何加?
@method_decorator(outter,name='get')
outter:装饰器名称
name=:指定哪个方法使用装饰器
# 定义一个计算执行时间的装饰器
def outter(func):
@wraps(func)
def inner(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
end_time = time.time()
print('执行时间:',end_time - start_time)
return res
return inner
# 导入装饰器的模块,官方推荐写法
from django.utils.decorators import method_decorator
# 第一种方式:可以指定给那个方法加
# @method_decorator(outter,name='get')
# @method_decorator(outter,name='post')
# @method_decorator(outter,name='dispatch')
class MyLogin(View):
# 第二种方式:在此重写父类dispatch方法,做一些操作,给所有的方法都加上装饰器。
@method_decorator(outter)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
# 第三中方法:可以单独在方法名称上加装饰器
# @method_decorator(outter)
def get(self,request):
print("我是MyLog里面的get方法")
return render(request,'login.html')
def post(self,request):
print("我是MyLog里面的post方法")
return HttpResponse("post")
执行结果:
我是MyLog里面的get方法
执行时间: 0.01500082015991211
我是MyLog里面的post方法
执行时间: 0.0
Django之深入了解视图层的更多相关文章
- django 实战篇之视图层
视图层(views.py) django必会三板斧 HttpResponse >>> 返回字符串 render >>> 支持模板语法,渲染页面,并返回给前端 red ...
- Django 路由层与视图层
1.路由层 1.1无名分组 1.2 有名分组 1.3 反向解析 1.4 路由分发 1.5 名称空间 2.伪静态网页 3.虚拟环境 4.视图层 1.1 JsonResponse 1.2 FBV与CBV ...
- Django路由层与视图层、pycharm虚拟环境
一. Django路由层 路由层即对应项目文件下的urls.py文件.实际上每个APP中也可以有自己的urls.py路由层.templates文件夹及static文件夹.Django支持这么做,也为实 ...
- Django路由层、视图层
一.路由匹配: 第一个参数是正则表达式,匹配规则按照从上往下一次匹配,匹配到一个后立即停止 urlpatterns = [ url(r'^admin/', admin.site.urls), url( ...
- Django的View(视图层)
目录 Django的View(视图层) 一.JsonResponse 二.后端接收前端的文件 三. FBV和CBV(源码分析) 四.settings.py配置文件源码分析 五. 请求对象(HttpRe ...
- Django路由层与视图层
表与表之间建关系 图书管理系统为例 书籍表 出版社表 作者表 三个表之间的关系: 考虑表之间的关系:换位思考 1.书籍和出版社是一对多,外键字段建立在书籍表中 2.书籍和作者是多对多, 需要建立第三方 ...
- web框架开发-Django视图层
视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . ...
- Django视图层
本文目录 1 视图函数 2 HttpRequest对象 3 HttpResponse对象 4 JsonResponse 5 CBV和FBV 6 简单文件上传 回到目录 1 视图函数 一个视图函数,简称 ...
- $Django 虚拟环境,2.0、1.0路由层区别,Httprequest对象,视图层(fbv,cbv),文件上传
1 虚拟环境:解决问题同一台机器上可以运行不同版本的django, 1 用pychanrm创建--->files-->newproject--->选择虚拟环境 2 setting ...
随机推荐
- CVE-2019-0708简单复现
各文件对应位置 rdp.rb -> /usr/share/metasploit-framework/lib/msf/core/exploit/rdp.rb rdp_scanner.rb -> ...
- 收藏的链接-English
What is the adverb for deposit? https://www.wordhippo.com/what-is/the-adverb-for/deposit.html
- 次梯度(Subgradient)
参考链接:https://closure11.com/subgradient/
- note : Get FilePathName from FILE_OBJECT
转自:http://blog.csdn.net/lostspeed/article/details/11738311 封了一个函数, 从 FILE_OBJECT 中 得到 FilePathName 在 ...
- sql中取出字符串中数字
select substring(reverse('0->星光'),PATINDEX('%[0-9]%',reverse('0->星光')),1)
- COGS2353 【HZOI2015】有标号的DAG计数 I
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 10007的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 25 提 ...
- linux上给其他在线用户发送信息(wall, write, talk, mesg)
linux上给其他在线用户发送信息(wall, write, talk, mesg) 2018-01-05 lonskyMR 转自 恶之一眉 修改 微信分享: 设置登录提示 /et ...
- lxhgww的奇思妙想 长链剖分板子
https://vijos.org/d/Bashu_OIers/p/5a79a3e1d3d8a103be7e2b81 求k级祖先,预处理nlogn,查询o1 //#pragma GCC optimiz ...
- luoguP1890 gcd区间 [st表][gcd]
题目描述 给定一行n个正整数a[1]..a[n]. m次询问,每次询问给定一个区间[L,R],输出a[L]..a[R]的最大公因数. 输入输出格式 输入格式: 第一行两个整数n,m. 第二行n个整数表 ...
- 分析post与json
寻找登录的post地址 在form表单中寻找action对应的url地址 post的数据是input标签中name的值作为键,真正的用户名密码作为值的字典,post的url地址就是action对应的u ...