Day 59
今日内容概要
- 路由层补充:网页伪静态
- 视图层
- 三板斧中视图函数的返回值问题
- 视图函数返回json格式数据(JsonResponse)
- form表单携带文件数据
- FBV与CBV(核心)
- CBV源码分析(重要)
- 模板层
- 模板语法传值
- 模板语法之过滤器
- 模板语法之标签
- 自定义过滤器、标签、inclusion_tag
- 模板的继承
- 模板的导入
今日内容详细
一.路由层补充:网页伪静态
将动态网页伪装成静态网页 从而提升网页被搜索引擎收录的概率(搜索引擎优先展示静态)
表现形式就是网址看着像一个具体的文件路径
path('index.html',view.index)
二.视图层
1.视图函数的返回值问题
视图函数'必须返回一个HttpResponse对象'
注意HttpResonse其实是一个类
class HttpResponse(HttpResponseBase):
pass
def render():
return HttpResponse(...)
def redirect(to, *args, permanent=False, **kwargs):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return redirect_class(resolve_url(to, *args, **kwargs))
通过查看三板斧里的(HttpResonse、render、redirect)底层源码发现他们最终都是继承了HttpResponse。所以视图函数必须返回一个HttpResponse对象是没问题的
2.视图函数返回json格式数据
#如果字典中有中文不想让中文序列化
【方式一:】用json.dumps 时 加入ensure_ascii=False
import json
def index(request):
user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
json_str = json.dumps(user_dict, ensure_ascii=False)
return HttpResponse(json_str)
【方式二:】导入from django.http import JsonResponse模块
from django.http import JsonResponse
def index(request):
user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
return JsonResponse(user_dict,json_dumps_params={'ensure_ascii':False})
#JsonResponse主要用来做字典的序列化,如果不是字典类型的则需要加一个参数safe为False
from django.http import JsonResponse
def index(request):
user_list=[11,22,33,'jason老师']
return JsonResponse(user_list,json_dumps_params={'ensure_ascii':False},safe=False)
3.form表单携带文件数据
form表单携带文件数据需要具备的条件:
【前端:】
1.method属性值必须是"post"
2.enctype属性值必须是"multipart/form-data"
【后端:】
request.FILES
request.POST获取的是其他数据
request.FILES获取的是文件数据
#可以自动区分出来各自获取各自的
4.FBV与CBV(核心)
FBV:基于函数的视图:
def index(request):
return HttpResponse()
path('index/', views.index)
CBV:基于类的视图:
from django import views
class MyView(views.View):
def get(self, request):
return HttpResponse('我是CBV里面的get方法')
def post(self, request):
return HttpResponse('我是CBV里面的post方法')
path('func/', views.MyView.as_view())
"""
CBV会自动根据请求方式的不同匹配类中定义的方法并自动执行
"""
5.CBV源码分析(重要)
源码分析入口
path('func/', views.MyView.as_view())
1.绑定给类的as_view方法
def as_view(...):
def view(...):
pass
return view
2.CBV路由匹配本质:跟FBV是一致的
path('func/', views.view)
3.浏览器访问func触发view执行
def view(...):
obj = cls()
return obj.dispatch()
'''涉及到对象点名字 一定要确定对象是谁 再确定查找顺序'''
4.研究dispatch方法
def dispatch(...):
func_name = getattr(obj,request.method.lower())
func_name(...)
三.模板层
1.模板语法传值
方式1:指名道姓 (数据较少时使用)
缺点:数据多的时候要写很多键值对
def modal(request):
name='jason'
age=18
return render(request,'modal.html',{'name':name,'age':age})
方式2:关键字locals() (数据较多时使用)
#将整个局部名称空间中的名字去全部传入页面
def modal(request):
name='jason'
age=18
...
return render(request,'modal.html',locals())
2.模板语法传值的范围
【基本数据类型:】直接传递使用
【函数名:】传递会自动加括号执行并将'返回值'展示到页面上
#函数如果有参数则不会执行也不会展示 模板语法不支持有参函数
【类名:】传递会自动加括号产生对象并展示到页面上
【对象:】传递则直接使用即可
ps:模板语法会判断每一个名字是否可调用 如果可以则调用!!!
"""django的模板语法在操作容器类型的时候只允许使用句点符"""
3.模板语法过滤器(类似于python内置函数)
<p>统计长度:{{ s|length }}</p>
<p>加法运算:{{ i|add:123 }} 加法运算:{{ s|add:'heiheihei' }}</p>
<p>日期转换:{{ s|date:'Y-m-d H:i:s' }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>数据切片:{{ l|slice:'0:10' }}</p>
<p>字符截取(...算一个字符):{{ s1|truncatechars:6 }}</p>#hello...
<p>单词截取(根据空格算一个单词):{{ s1|truncatewords:6 }}</p>
#语法转义就类似于在后端写一个前端的代码,前端展示时显示代码还是样式。显示样式需要加safe
<p>语法转义:{{ script_tag|safe }}</p>
from django.utils.safestring import mark_safe
script_tag1 = '<script>alert(666)</script>'
res = mark_safe(script_tag1)
ps:有时候html页面上的数据不一定非要在html页面上编写了 也可以后端写好传入
'''
django模板语法中的符号就两个 一个{{}} 一个{%%}
需要使用数据的时候 {{ }}
需要使用方法的时候 {% %}
'''
4.模板语法标签(类似于python流程控制)
{% if 条件 %} #条件一般是模板语法传过来的数据 直接写名字使用即可
条件成立执行的代码
{% elif 条件1 %}
条件1成立执行的代码
{% else %}
条件都不成立执行的代码
{% endif %}
{% for i in s %}
{% if forloop.first %}
<p>这是第一次</p>
{% elif forloop.last %}
<p>这是最后一次</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{% empty %}#专门用来判断i是不是空的
<p>你给我的是个空 怎么for循环呢</p>
{% endfor %}
5.自定义过滤器、标签函数、inclusion_tag
"""
如果想自定义 必须先做以下三件事
1.在应用文件下创建一个名为templatetags文件夹(名字不能错)
2.在该文件夹创建任意名称的py文件
3.在该py文件内编写自定义相关代码
from django.template import Library
register = Library()
"""
# 自定义过滤器(过滤器最多只能有两个参数 自带的也好自定义的也好)
@register.filter(name='myfilter')
def my_add(a, b):
return a + b
# 自定义标签函数
@register.simple_tag(name='mt')
def func(a, b, c, d):
return a + b + c + d
# 自定义inclusion_tag
@register.inclusion_tag(filename='it.html')
def index(n):
html = []
for i in range(n):
html.append('第%s页'%i)
return locals()
#然后在任意Html页面就可以使用自定义的模板语法
{% load mytag %}
{{ i|myfilter:1 }}
{% mt 1 2 3 4 %}
{% index 10 %}
6.模板的继承
#继承页面需要给要更改的原页面区域写一个名字:{% block 名字 %}
【主页:】
{% block 名字 %} #继承页面要更改的区域名字
母板内容 #主页中可能要被替换的内容
{% endblock %} #结束
【子页:】
{% extends 'html文件名' %} #继承的页面
{% block 名字 %} #要更改主页面里哪个区域的名字
子板内容 #子页中要替换为的内容
{% endblock %} #结束
'''
一般情况下母板(主页)中至少应该有三个区域,使得扩展性更高!!!
css、content(替换的名字)、js
目的是可以让各个子板(子页)中有各自的css和js!
'''
{% block css %}#主页中在<head>中写css(主页里的css不用写东西)
{% endblock %}
{% block content替换名字 %} #主页中在<body>中写content
母板内容
{% endblock %}
{% block js %}#主页中在<body>结尾写js(主页里的js不用写东西)
{% endblock %}
'''子板中也可以使用母板的内容 {{ block.super }} '''
7.模板的导入(了解)
将html页面的某个部分当做模块的形式导入给其他页面使用
直接在要导入的地方用include '页面名'即可
{% include 'menu.html' %}
#仅适用于页面某个小的区域,不适用整个页面
作业
1.整理今日内容及博客
2.将用户管理系统再优化一下 使用上今天讲得一些内容
3.预习django模型层
4.周末查缺补漏 留给你们追赶的实际不多了!!!
标签:return,python,request,学习,Day59,html,def,模板,页面
From: https://www.cnblogs.com/Oreoxx/p/16656324.html