视图层:三板斧问题,JsonResponse序列化,form表单上传文件,request对象的其他几个方法,CBV的书写和FBV的写法,CBV的源码分析.模板层:变量之分配,过滤器
视图层
三板斧问题
"""
httpResponse
返回字符串
render
返回html文件
redirect
重定向
return redirect('https:www.baidu.com/') 跳转别人的网址
return redirect('/home/') 跳转自己的网址
"""
# 在视图函数中写函数跟普通函数不太一样
# djagno中使用的局部的request
def index(request):
pass
def func(request):
pass
'''所有的视图函数不能够没有返回值,并且返回值还必须是HttpResponse对象'''
The view app01.views.index didn't return an HttpResponse object.
It returned None instead.

# 其实我们的三板斧方法返回的都是HttpResponse对象
# 在flask中request使用的是全局的request
from ... import request
def index():
pass
def func():
pass
# 所有的视图函数都使用全局的request对象,会不会乱套? 不会乱套,如何做到不乱套的? 在源码中揭晓.
JsonResponse序列化
# json格式的数据?
主要就是实现跨语言数据传输
# 现在实现跨语言数据的传输使用的都是json,在以前使用的是xml
# 微信支付朝微信的后端发送参数的时候,使用的就是xml
json格式的数据特点:
{"username":"kevin","age":18}
{"username":"kevin","age":18}
# 之前学的是如何序列化的?
import json
json.dumps -------------》 JSON.stringify()
json.loads -----------》JSON.parse()
# 在js中是如何做的
JSON.stringify()
JSON.parse() # 对象
# 在Django中又该如何去序列化
# js中的对象
obj = new Object() # {}
obj = {} # {}
obj.username = 'kevin' # {'username':'kevin'}
consolo.log(obj.username)
------------------------------------------------------------------------
import json
from django.http import JsonResponse
from django.shortcuts import HttpResponse
# Create your views here.
def index(request):
user_dict = {'username': '小红帽', 'password': 123, 'hobby': 'looking TV'}
json_str = json.dumps(user_dict, ensure_ascii=False)
# ensure_ascii=False 只是将字符串单引号变为双引号,不要转换中文,中文正常显示
# 将该字符串返回
return HttpResponse(json_str)
# 读源码掌握用法
# return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})
# In order to allow non-dict objects to be serialized set the safe parameter to False.
# 列表
# list = [1, 2, 3, 4]
# 默认只能序列化字典 序列化其他需要加safe参数
# return JsonResponse(list, safe=False)
-
列表形式

-
字典形式

form表单上传文件
# form表单上传文件的前提:
1. 请求方式必须是post
2. enctype必须是form-data

request对象的其他几个方法
request.GET
request.POST
request.FILES
request.path_info # /ab_request/
reqeust.path # /ab_request/
request.get_full_path() # /ab_request/ /ab_request/?username=kevin&age=11
# get_full_path()会接收路径后面的参数
request.body # 现在先不学,它能够接收浏览器发过来的二进制数据,BBS项目中学
C(class)BV的书写和F(function)BV的写法
# 目前写的都是FBV:function based view 基于函数的视图
# 在视图文件中书写类 CBV:class based view 基于类的视图
postman的官网地址:https://www.postman.com/downloads/
apizza的挂网地址:http://www.apizza.net/
# 所有的类必须继承django的view类
from django.views import View
class MyLogin(View):
# 类里面的方法名字不能够随便写,目前只能写get post等
# 访问这个地址必须是get请求方式
def get(self, request):
# get() takes 1 positional argument but 2 were given
print("get")
return HttpResponse("get")
# 访问这个方法必须是psot请求方式
# 通过form表单发送post请求
# 出了form表单,我们还可以使用工具来模拟
def post(self,request):
print("post")
return HttpResponse("post")
CBV的源码分析
# 我们第一次看Django的源码,面试题:你都看过Django的哪些源码,简单说说?
# CBV的源码、settings的源码、权限、频率、认证的、签发token的源码
一、CBV源码分析
准备工作:
新建一个Django项目
写一个基于类的视图
继承,写get,post方法
from django.shortcuts import render, HttpResponse
from django.views import View
from django.http import JsonResponse
# Create your views here.
class Test(View):
def dispatch(self, request, *args, **kwargs):
# codes
obj = super().dispatch(self, request, *args, **kwargs)
# codes
return obj
def get(self, request, *args, **kwargs):
return HttpResponse('cbv_get')
def post(self, request, *args, **kwargs):
return HttpResponse('cbv_post')
视图写好之后写路由
把views导过来,
类名.as_view() 直接执行
from django.conf.urls import url
from django.contrib import admin
from appp01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 在这里写的 views.Test.as_view(),实际上就是as_view()里面view的内存地址
url(r'^test/', views.Test.as_view()),
]
分析一下执行的流程:
1. 如果当初放的是函数内存地址不会去执行,请求来了经过路由做分发。
但是如果放的是函数加括号直接就执行了(程序一点一运行立马这里就执行),
执行Test.as_view的方法,
2. Test里面没有as_view,所以执行的是父类View里面的as_view方法
3. 打开父类的View找到as_view方法,类来调用就把类传入,定义了一个view函数,
最后返回了这个view,所以在路由层写的实际上就是view(as_view()内部的)
这个函数的内存地址。
4. 当请求来了,来了执行的实际上就是view加括号执行。在执行前
这里面外层函数有个cls(这个cls就是Test这个类,产生了对象赋值给了self。),
在内部函数有个对外部作用域的引用,所以这个view就是一个闭包函数。
5. 把请求的request对象赋到了self.request里面
return self.dispatch(request, *args, **kwargs)
7. 最后返回了一个self.dispatch函数,其实就是在执行这个函数。

8. 这个dispatch函数就是生成的Test这个类的,这个Test类里面没有这个dispatch,
所以执行的是View的dispatch。
9. 所以请求来了就是执行dispatch方法
10. 这里面取到请求的小写,判断在不在self.http_method_names中,
如果是get请求在这个列表里面
11. 通过getattr反射,self是Test对象,找到get方法,
找不到返回错误提示(self.http_method_not_allowed)
handler=test对象中get方法的内存地址,

两层判断:
--------------------------看self.http_method_names源码--------------------------------
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
-------------------------------------------------------------------------------------
-------------------------self.http_method_not_allowed源码-----------------------------
def http_method_not_allowed(self, request, *args, **kwargs):
logger.warning(
'Method Not Allowed (%s): %s', request.method, request.path,
extra={'status_code': 405, 'request': request}
)
return HttpResponseNotAllowed(self._allowed_methods())
def options(self, request, *args, **kwargs):
"""Handle responding to requests for the OPTIONS HTTP verb."""
response = HttpResponse()
response['Allow'] = ', '.join(self._allowed_methods())
response['Content-Length'] = '0'
return response
def _allowed_methods(self):
return [m.upper() for m in self.http_method_names if hasattr(self, m)]
--------------------------------------------------------------------------------------
总结:
源码执行的流程?
CBV源码分析
cbv和fbv
1 在views中写一个类,继承View,里面写get方法,post方法
2 在路由中配置: url(r'^test/', views.Test.as_view()),实际上第二个参数位置,
放的还是一个函数内存地址
3 当请求来了,就会执行第二个参数(request,参数),本质上执行view()
4 view内部调用了dispatch()方法
5 dispatch分发方法,根据请求方式不同,执行的方法不同
模板层
模板变量之分配
模板中的变量格式为:{{ 变量名 }}。
# 模板中取值一定使用的是句点符.
变量名中不能有空格或者标点符号,但是有一个例外,点(".")可以出现在变量中,
点后的可以是字典相关(字典的key或者字典内置方法)、对象的属性或方法、数字索引
# 模板中的函数一定不能够加括号,他们会自动帮你加括号调用
模板之过滤器
'''常用过滤器基本使用'''
Django自带的过滤器有好几十、但是我们没必要全部记住,只需要记住几个就行了
语法:
#1、
{{ 变量名|过滤器名 }}
#2、链式调用:上一个过滤器的结果继续被下一个过滤器处理
{{ 变量名|过滤器1|过滤器2 }}
#3、有的过滤器取需要参数
{{ 变量名|过滤器名:传给过滤器的参数 }}
//常用内置过滤器//
#0、default
#作用:如果一个变量值是False或者为空、None,使用default后指定的默认值,
否则,使用变量本身的值,如果value=’‘则输出“nothing”
{{ value|default:"nothing" }}
#1、default_if_none
#作用:如果只针对value是None这一种情况来设置默认值,需要使用default_if_none
#只有在value=None的情况下,才会输出“None...”,
{{ value|default_if_none:"None..." }}
#2、length
#作用:返回值的长度。它对字符串、列表、字典等容器类型都起作用,
如果value是 ['a', 'b', 'c', 'd'],那么输出是4
{{ value|length }}
#3、filesizeformat
#作用:将值的格式化为一个"人类可读的"文件尺寸(如13KB、4.1 MB、102bytes等等),
如果 value 是 12312312321,输出将会是 11.5 GB
{{ value|filesizeformat }}
#4、date
#作用:将日期按照指定的格式输出,如果value=datetime.datetime.now(),
按照格式Y-m-d则输出2019-02-02
{{ value|date:"Y-m-d" }}
#5、slice
#作用:对输出的字符串进行切片操作,顾头不顾尾,如果value=“egon“,则输出"eg"
{{ value|slice:"0:2" }}
#6、truncatechars
#作用:如果字符串字符多于指定的字符数量,那么会被截断。
截断的字符串将以可翻译的省略号序列(“...”)结尾,
如果value=”hello world egon 嘎嘎“,则输出"hello...",
注意8个字符也包含末尾的3个点
{{ value|truncatechars:8 }}
#7、truncatewords
#作用:同truncatechars,但truncatewords是按照单词截断,
注意末尾的3个点不算作单词,如果value=”hello world egon 嘎嘎“,
则输出"hello world ..."
{{ value|truncatewords:2 }}
其他请参考以下链接:
https://www.yuque.com/liyangqit/lb35ya/qclygk?inner=cde6dc1c

浙公网安备 33010602011771号