python之路48 django 视图层、模板层 fbv cbv源码分析
视图层之必会三板斧
用来处理请求的视图函数都必须返回HttpResponse对象
完全正确
class HttpResponse:
pass
return HttpResponse()
def render():
return HttpResponse()
return render()
def redirect():
redirect_class = 类(祖先有个类是HttpResponse)
return redirect_class()
return redirect()
JsonResponse对象
from django.http import JsonResponse
def index_func(request):
# return HttpResponse('哈哈哈')
# return render()
# return redirect()
# 返回给浏览器一个json格式的字符串
# user_dict = {'name': 'jason老师', 'age': 18}
user_list = [11,22,33,44,555,666,77,]
# import json
# user_json = json.dumps(user_dict, ensure_ascii=False)
# return HttpResponse(user_json)
# return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
return JsonResponse(user_list,json_dumps_params={'ensure_ascii':False},safe = False)
ps:以后写代码很多时候可能需要参考源码及所学知识扩展功能
class JsonResponse():
def __init__(self,data,json_dumps_params=None):
json.dumps(data,**json_dumps_params)
JsonResponse主要序列化字典针对非字典的其他可以被序列化的数据需要修改safe参数为False
视图层之request对象获取文件
form表单携带文件类型的数据需要做到以下几点
1.method必须是post
2.enctype必须是multipart/form-data
django后端需要通过request.FILES获取文件类型的数据
if request.method == 'POST':
# print(request.POST) # 获取普通数据(输入、选择)
# print(request.FILES) # 获取文件数据(上传)
file_obj= request.FILES.get('file')
print(file_obj.name) # 获取文件名称
with open(r'%s' % file_obj.name,'wb')as f:
for line in file_obj:
f.write(line)
return render(request, 'indexPage.html')
这段代码是一部分还有其他的 一个上传文件的获取
视图层之FBV与CBV
FBV(function base views)
基于函数的视图
def index(request):return HttpResponse对象
CBV(class base views)
基于类的视图
from django import views
class MyLoginView(views.View):
def get(self, request):
return HttpResponse('from CBV get function')
def post(self, request):
return HttpResponse('from CBV post function')
path('login/',views.MyLoginView.as_view()),
会自动根据请求方法的不同自动匹配对应的方法并执行
CBV源码剖析(重要)
1.从CBV的路由匹配切入
path('login/',views.MyLoginView.as_view())
1.类名点名字(名字的查找问题)
2.类名点名字并加括号调用(静态方法、绑定给类的方法)
2.函数名加括号执行优先级最高 项目一启动就会自动执行as_view方法
path('login/',views.view) # CBV路由本质还是FBV
3.浏览器地址栏访问login路由需要执行view函数
1.产生我们自己编写类的对象
2.对象调用dispatch方法(注意查找顺序)
4.研究父类中的dispatch方法
获取当前请求方法并转小写 之后利用反射获取类中对应的方法并执行
以下只是源码中一部分
class View:
@classmethod
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
self = cls(**initkwargs)
return self.dispatch(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs):
handler = getattr(self, request.method.lower())
return handler(request, *args, **kwargs)
模板层
"""
{{}}:主要与数据值相关
{%%}:主要与逻辑相关
django的模板语法是自己写的 跟jinja2不一样
1.针对需要加括号调用的名字 django模板语法会自动加括号调用 你只需要写名字就行
2.模板语法的注释前端浏览器是无法查看的{##}
"""
1.模板语法传值
return render(request,'demo02.html',{'n1':name,'a1':age}) # 传值方式1:精准传值 不浪费资源针对多资源的传递书写麻烦
return render(request,'demo02.html',locals()) # 传值方式2:将函数名称空间中所有的名字全部传递 名字过多并且不使用的情况下比较浪费资源
2.模板语法传值特性
1.基本数据类型正常展示
2.文件对象也可以展示并调用方法
3.函数名会自动加括号执行并将返回值展示到页面上(不支持额外传参)
4.类名也会自动加括号调用
5.对象则不会
ps:总结针对可以加括号调用的名字模板语法都会自动加括号调用
3.模板语法之过滤器(内置函数)
Filters(过滤器)
在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
过滤器的语法: {{ value|filter_name:参数 }}
使用管道符"|"来应用过滤器。
例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。
注意事项:
- 过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
- 过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
- 过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
- '|'左右没有空格没有空格没有空格
Django的模板语言中提供了大约六十个内置过滤器。
default
如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值。
{{ value|default:"nothing"}}
如果value没有传值或者值为空的话就显示nothing
length
返回值的长度,作用于字符串和列表。
{{ value|length }}
返回value的长度,如 value=['a','b','c','d']的话,就显示4.
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7 MB。
slice
切片
{{value|slice:"2:-1"}}
date
格式化
{{ value|date:"Y-m-d H:i:s"}}
偷懒 截个图
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
比如:
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:截断的字符数
{{ value|truncatechars:9}}
truncatewords
在一定数量的字后截断字符串。
{{ value|truncatewords:9}}
cut
移除value中所有的与给出的变量相同的字符串
{{ value|cut:' ' }}
如果value为'i love you',那么将输出'iloveyou'.
join
使用字符串连接列表,例如Python的str.join(list)
timesince
将日期格式设为自该日期起的时间(例如,“4天,6小时”)。
采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:
{{ blog_date|timesince:comment_date }}
分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。
timeuntil
似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。
使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:
{{ conference_date|timeuntil:from_date }}