一:视图层

Django视图层,视图就是Django项目下的views.py文件,她的内部是一系列的函数或者是类,用来专门处理客户端访问请求后处理请求并且返回相应的数据,相当于一个中央情报处理系统。
2.三板斧(HttpResponse对象)
"""
HttpResponse
返回字符串类型
render
返回html页面 并且在返回给浏览器之前还可以给html文件传值
redirect
重定向
"""
4.HttpResponse()
  • 返回字符串类型的数据
httpresponse() 括号内直接跟一个具体的字符串作为响应体,比较直接简单,所有这里主要介绍后面两种形式。
5.render()
  • 返回html页面,还可以使用模板语法
render(request, template_name[, context])结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

# 参数:
request: 用于生成响应的请求对象。 template_name:要使用的模板的完整名称,可选的参数 context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。 render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体。
6.redirect()
  • 传递要重定向的一个硬编码的URL
def my_view(request):
rerurn redirect('/some/url/')
7.也可以是一个完整的URL
def my_view(request):
...
return redirect('http://www.baidu.com/')
1)301和302的区别。

301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到
一个新的URL地址,这个地址可以从响应的Location首部中获取
(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。 他们的不同在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),
搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址; 302表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B,
搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301 2)重定向原因:
(1)网站调整(如改变网页目录结构);
(2)网页被移到一个新地址;
(3)网页扩展名改变(如应用需要把.php改成.Html或.shtml)。
这种情况下,如果不做重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让
访问客户得到一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的
网站,也需要通过重定向让访问这些域名的用户自动跳转到主站点等。

二:三板斧本质

1.Django图层函数必须要返回一个HttpResponse对象
Django视图层函数必须要返回一个HttpResponse对象!   正确!
django视图层函数必须有一个返回值,并且返回值的数据类型必须是HttpResponse对象
2.研究三者的源码即可得处结论
# HttpResponse
class HttpResponse(HttpResponseBase):
"""
An HTTP response class with a string as content.
# 以字符串作为内容的HTTP响应类
This content that can be read, appended to or replaced.
# 可以读取、添加或替换的内容
"""
streaming = False
def __init__(self, content=b'', *args, **kwargs):
super(HttpResponse, self).__init__(*args, **kwargs)
# 内容是一个字符串 参见'content'属性方法
# Content is a bytestring. See the `content` property methods.
self.content = content # render简单内部原理
from django.template import Template,Context
res = Template('<h1>{{ user }}</h1>')
con = Context({'user':{'username':'jason','password':123}})
ret = res.render(con)
print(ret)
return HttpResponse(ret) # redirect
class HttpResponseRedirectBase(HttpResponse): eg: redirect内部是继承了HttpRespone类

三:JsonResponse对象

1.json格式的数据有什么用?
前后端数据交互需要使用到json作为序列化,实现跨语言数据传输。
1. 混合开发项目:前端页面和后端代码写到一块
2. 前后端分离项目:前端是一个项目,后端是一个项目,后端只需要写接口
前端js序列化								后端序列化
JSON.stringify() json.dumps()
JSON.parse() json.loads()
2.给前端浏览器返回一个json格式的字符串
3.json序列化
# 导入模块
import json def ab_json(request):
# 将后端字典序列化发送到前端
user_dict = {'username':'jason帅哥,我爱你', 'password':'123', 'hobby':'girl'}
# 先转成json格式字符串
# ensure_ascii 内部默认True自动转码,改为False不转码,只生成json格式,双引号
json_str = json.dumps(user_dict,ensure_ascii=False)
# 将该字段返回
return HttpResponse(json_str) ensure_ascii 内部默认True自动转码,改为False不转码,只生成json格式,双引号

4.JsonResponse序列化
# 导入JsonResponse模块
from django.http import JsonResponse def ab_json(request):
# 将后端字典序列化发送到前端
user_dict = {'username':'jason帅哥,我爱你', 'password':'123', 'hobby':'girl'}
# JsonResponse自动编码并返回给前端页面
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False}) user_dict,json_dumps_params={'ensure_ascii':False} :解决前端汉字转码问题

5.JsonResponse序列化(列表注意事项)
# 导入JsonResponse模块
from django.http import JsonResponse def ab_json(request):
l = [111,222,333,444,555]
# 默认只能序列化字典 序列化其他需要加safe参数 safe=False
return JsonResponse(l,safe=False)
6.json与pickle区别
import json
'''支持的数据类型:str,list, tuple, dict, set'''
# 序列化出来的数据是可以看得懂的,就是一个字符串
dumps
loads dump
load import pickle
'''支持的数据类型:python中的所有数据类型'''
# 序列化出来的结果看不懂,因为结果是一个二进制
# pickle序列化出的来的数据只能在python中使用
dumps
loads dump
load

四:form表单上传文件及后端如何操作

1.上传文件注意事项
form表单上传文件类型的数据
1.method必须指定成post
2.enctype='multipart/form-data' 后端:
在request.FILES中接收文件数据,其他数据一律按照请求方式接收
2.form表单上传文件
# views.py文件

def ab_file(request):
# 判断前端请求
if request.method == 'POST':
# 获取POST请求信息
# print(request.POST) # 只能获取普通的键值对数据 文件不行 <QueryDict: {'username': ['json']}>
print(request.FILES) # 获取文件数据
# < MultiValueDict: {'username': [ < InMemoryUploadedFile: 双层语法糖2.png(image / png) >]} >
file_obj = request.FILES.get('file') # (拿到最后一个元素) 文件对象
print(file_obj.name) # 拿到文件名字
# 将文件存起来 先打开文件
with open(file_obj.name, 'wb') as f:
# for循环 一行一行的读取文件内容
for line in file_obj.chunks(): # 推荐加上chunks方法 其实跟不加是一样的都是一行行的读取
# 将文件保存
f.write(line)
# get请求返回
return render(request, 'from.html') # from.py文件 {# 1.method必须指定成post 2.enctype必须换成formdat #}
<form action="" method="post" enctype="multipart/form-data">
<p>username: <input type="text" name="username"></p>
<p>file: <input type="file" name="file"></p>
<input type="submit">
</form>

五:request对象方法

1.获取请求方式POST/GET
request.method
一个字符串,表示请求使用的HTTP 方法。必须使用大写。 2.request.POST
获取POST请求提交普通的键值对数据 一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 3.获取GET请求
request.GET
获取GET请求 一个类似于字典的对象,包含 HTTP GET 的所有参数 4.获取文件
request.FILES
一个类似于字典的对象,包含所有的上传文件信息。
FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。
注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会包含数据。否则,FILES 将为一个空的类似于字典的对象。 5.原生的浏览器发过来的二进制数据
request.body
一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,
  例如:二进制图片、XML,Json等。 6.拿到路由
request.path
个字符串,表示请求的路径组件(不含域名) 7.拿到路由
request.path_info 8.能过获取完整的url及问号后面的参数
request.get_full_path()

案列演示:
print(request.path) # /app01/ab_file/
print(request.path_info) # /app01/ab_file/
print(request.get_full_path()) # /app01/ab_file/?username=jason

六:FBV与CBV

1.FBV与CBV区别?
FBV基于函数的视图(Function base view) 我们前面写的视图函数都是FBV
CBV基于类的视图(Class base view)
视图文件种除了用一系列的函数来对应处理客户端请求的数据逻辑外,还可以通过定义类来处理相应的逻辑。
# 视图函数既可以是函数也可以是类
def index(request):
return HttpResponse('index')
2.CBV实际应用
# CBV路由
url(r'^login/', views.MyLogin.as_view()) # 加as_view参数 # 导入CBV模块
from django.views import View # 继承模块
class MyLogin(View):
# 前端发起get请求走get函数
def get(self, request):
return render(request, 'from.html') # 前端发起post请求走该post函数
def post(self,request):
return HttpResponse('post方法')

FBV和CBV各有千秋
CBV特点
能够直接根据请求方式的不同直接匹配到对应的方法执行

七:CBV的源码剖析

1.CBV本质上跟FBV是一样的
urlpatterns = {
url(r'^login/', views.MyLogin.as_view())
# CBV于FBV在路由匹配上本质是一样的 都是路由 对应 函数内存地址
# url(r'^login/', views.view) # CBV与FBV本质一模一样
}
2.突破口:
知识点: 函数名/方法名: 加括号执行优先级最高
CBV写的是as_view(), 加括号意味着在项目启动的时候就会执行,那么猜测
要么是被@staicmethod修饰的静态方法,就是个普通函数没有形参
要么是被@classmethod修饰的类方法,类来调用自动将类传入当做第一个参数传入
3.CBV源码as_view解析(分步执行流程 全面扩展)
  • 1.0

urlpatterns = [
# MyLogin类 点 方法
​ url(r'^login/', views.MyLogin.as_view())
]

  • 2.0

函数名/方法名 加括号执行优先级最高 类来调用方法,没有传参数,那么要么是以下两种
as_view()
要么是被@staicmethod修饰的静态方法
要么是被@classmethod修饰的类方法 # 源码显示
@classonlymethod # 绑定给类的方法
def as_view(cls, **initkwargs):
pass
as_view : 绑定给类的方法,类来调用把类传进去
  • 3.0

# 闭包函数(内部函数引用外部函数名称空间中的名字)
def view(request, *args, **kwargs): # 1.返回值是闭包函数的函数名
return view
  • 4.0

代码在启动django的时候 就会立刻执行as_view方法
url(r'^login/', views.MyLogin.as_view()) # as_view 返回值 view django代码运行 以上代码就等价于以下代码段 CBV与FBV在路由匹配上本质一样的 都是路由 对应 函数内存地址
url(r'^login/', views.view) django项目启动就等价于这个方法 view什么时候触发?
当用户在浏览器输入login的时候就自动执行 view方法
  • 5.0


# 闭包函数(内部函数引用外部函数名称空间中的名字)
def view(request, *args, **kwargs):
self = cls(**initkwargs) # cls是我们自己写的类的对象
# self = MyLogin(**initkwargs) 产生一个我们自己写的类对象 # hasattr 映射 判断对象是否包含对应属性 (对象有该属性返回True 否则返回False)
if hasattr(self, 'get') and not hasattr(self, 'head'):
# 给对象赋值属性
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
# 对象点dispatch
return self.dispatch(request, *args, **kwargs)
# 面向对象属性方法查找顺序
1.先从对象自己名称空间找
2.在去产生类对象的类里面找
3.在去父类里面找 MyLogin >>名称空间中查找 >>产生类对象的类里面找 >>父类查找 class MyLogin(View): # 父类查找
  • 6.0
def dispatch(self, request, *args, **kwargs):
# 判断 request.method将当前请求方式转成小写 在不在 self内 self==MyLogin
"http_method_names 内有八个请求方式 合法"
['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
if request.method.lower() in self.http_method_names:
"""
# getattr 反射: 通过字符串来操作对象的属性或者方法
# handler = gertattr(self,'get'),你写的Book类的get方法的内存地址
# handler = getattr(自己写的类产生的对象,'get',当找不到get属性或者方法的时候就会用第三个参数)
"""
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) # 执行get(request)
  • 7.0
  • 执行类,执行该类就又是之前的FBV
class Book(View):
def get(self, request):
return HttpResponse('ok')
4.总结:
结论: as_view() 最终干的事情就是根据request请求方式来执行视图类的不同请求方法

以后会经常需要看源码,但是在看python源码的时候:
一定要时刻提醒自己面向对象属性方法查找顺序
1.先从对象自己找
2.在去产生对象的类里找
3.之后在去父类找 看源码只要看到了self点一个东西,一定要问自己当前这个self到底是谁。

Django框架三板斧本质-jsonResponse对象-form表单上传文件request对象方法-FBV与CBV区别的更多相关文章

  1. JsonResponse类的使用、form表单上传文件补充、CBV和FBV、HTML的模板语法之传值与过滤器

    昨日内容回顾 Django请求生命周期 # 1.浏览器发起请求 到达Django的socket服务端(web服务网关接口) 01 wsgiref 02 uwsgi + nginx 03 WSGI协议 ...

  2. django 基于form表单上传文件和基于ajax上传文件

    一.基于form表单上传文件 1.html里是有一个input type="file" 和 ‘submit’的标签 2.vies.py def fileupload(request ...

  3. 巨蟒python全栈开发django11:ajax&&form表单上传文件contentType

    回顾: 什么是异步? 可以开出一个线程,我发出请求,不用等待返回,可以做其他事情. 什么是同步? 同步就是,我发送出了一个请求,需要等待返回给我信息,我才可以操作其他事情. 局部刷新是什么? 通过jq ...

  4. vue form表单上传文件

    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...

  5. 使用form表单上传文件

    在使用form表单上传文件时候,input[type='file']是必然会用的,其中有一些小坑需要避免. 1.form的 enctype="multipart/form-data" ...

  6. form表单上传文件使用multipart请求处理

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——spring MVC其中的一个优势.Spring通过对Serv ...

  7. form表单上传文件

    一.formData()直接获取form表单数据 例子:获取form表单的id给formData(),然后传给后台. 要求: 传入值的name值必须与后台接受的name相对应. form表单不能嵌套, ...

  8. ajax上传文件 基于jquery form表单上传文件

    <script src="/static/js/jquery.js"></script><script> $("#reg-btn&qu ...

  9. PHP 后台程序配置config文件,及form表单上传文件

    一,配置config文件 1获取config.php文件数组, 2获取form 表单提交的值 3保存更新config.php文件,代码如下: $color=$_POST['color']; $back ...

  10. nodejs 模拟form表单上传文件

    使用nodejs来模拟form表单进行文件上传,可以同时上传多个文件. 以前项目里有这个方法,最近在客户那里出问题了,同事说,这个方法从来就没管用过,SO,用了一天时间把这个方法给搞出来了(觉得花费的 ...

随机推荐

  1. 【JAVA】普通IO数据拷贝次数的问题探讨

    最近看到网上有些文章在讨论JAVA中普通文件IO读/写的时候经过了几次数据拷贝,如果从系统调用开始分析,以读取文件为例,数据的读取过程如下(以缓存I/O为例): 应用程序调用read函数发起系统调用, ...

  2. EasyExcel实现文件导出

    官网:https://www.yuque.com/easyexcel/doc/easyexcel 导出 准备工作 引入依赖 <!--EasyExcel相关依赖--> <depende ...

  3. 无需Steam的Proton,在你的Linux运行任意Windows游戏!

    链接: https://pan.baidu.com/s/1QeJxj9_2aZPk2_uZMzpn9A 提取码: v6t6 包含的版本 Proton4.11  Proton4.2  Proton5.0 ...

  4. [笔记] 二维FFT

    假设现在有2个矩阵a和b,分别是n行m列和x行y列,现在你要计算它们的二维卷积,也就是求出矩阵s满足: \(s_{i,j}=\sum_{i'\leq i,j'\leq j}a_{i',j'}b_{i- ...

  5. [题解] Codeforces 438 E The Child and Binary Tree DP,多项式,生成函数

    题目 首先令\(f_i\)表示权值和为\(i\)的二叉树数量,\(f_0=1\). 转移为:\(f_k=\sum_{i=0}^n \sum_{j=0}^{k-c_i}f_j f_{k-c_i-j}\) ...

  6. JavaScript基础&实战(3)js中的流程控制语句、条件分支语句、for循环、while循环

    文章目录 1.流程控制语句 1.1 代码 1.2 测试结果 2.弹窗提示输入内容 2.1 代码 2.2 测试结果 3.条件分支语句 3.1 代码 3.2 测试结果 4.while和 do...whil ...

  7. Istio(十一):向istio服务网格中引入虚拟机

    目录 一.模块概览 二.系统环境 三.虚拟机负载 3.1 虚拟机负载 3.2 单网络架构 3.3 多网络架构 3.4 Istio 中如何表示虚拟机工作负载? 四.实战:向istio Mesh中引入虚拟 ...

  8. 系统整理K8S的配置管理实战-建议收藏系列

    目录 一.ConfigMap 1.1.创建 1.1.1.from-file 1.1.2.from-env-file 1.1.3.from-literal 1.1.4.基于yaml文件创建 1.2.Po ...

  9. SimpleDateFormat线程安全问题排查

    一. 问题现象 运营部门反馈使用小程序配置的拉新现金红包活动二维码,在扫码后跳转至404页面. 二. 原因排查 首先,检查扫码后的跳转链接地址不是对应二维码的实际URL,根据代码逻辑推测,可能是acc ...

  10. WPF之MVVM实践中的Command与CommandParameter

    先记录一下,方便以后复习. https://www.cnblogs.com/babietongtianta/p/3474101.html