【Django】 第04回 视图层与模板层
目录
1. 网页伪静态
将动态网页伪装成静态网页,从而提升网页被搜索引擎收录的概率表现形式就是网址看着像一个具体的文件路径
2. 视图层
2.1 视图函数的返回值问题
1. 视图函数必须返回一个HttpResponse对象
2. 注意HttpResonse其实是一个类
HttpResonse
class HttpResponse(HttpResponseBase):
pass
HttpResonse其实是一个类
render
def render():
return HttpResponse(...)
返回一个HttpResponse对象
redirect
def redirect(to, *args, permanent=False, **kwargs):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return redirect_class(resolve_url(to, *args, **kwargs))
到
class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
status_code = 301
到
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']
返回一个HttpResponse对象
2.2 视图函数返回json格式数据
json模块
dumps() 将其他数据类型转换成json格式字符串
loads() 将json格式字符串转化成对应的数据类型
dump() 将其他数据数据以json格式字符串写入文件
load() 将文件中json格式字符串读取出来并转换成对应的数据类型
导入json模块
import json
def index(request):
user_dict = {'name': 'jason','pwd':123, 'hobby':['read','run','music']}
json_str = json.dumps(user_dict)
return HttpResponse(json_str)
缺陷中文编码
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)
编码问题,如果有中文,得加上ensure_ascil=False
JsonResponse
from django.http import JsonResponse
def index(request):
user_dict = {'name': 'jason老师', 'pwd': 123, 'hobby': ['read', 'run', 'music']}
return JsonResponse(user_dict)
底层逻辑
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super().__init__(content=data, **kwargs)
JsonResponse中文解码问题
由底层逻辑看出,给形参传个字典,不走if分支,接收拿到
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})
2.3 from表单携带文件数据
def index(request):
if request.method == 'POST':
print(request.POST)
return render(request, 'index.html')
form表单携带文件数据,form表单需要具备的条件
1.method属性值必须是post
2.enctype属性值必须是multipart/form-data
3.后端获取文件数据的操作 request.FILES
def index(request):
if request.method == 'POST':
print('request.POST', request.POST)
print('request.FILES', request.FILES)
file_obj = request.FILES.get('file')
print(file_obj.name)
with open(file_obj.name, 'wb') as f:
for line in file_obj:
f.write(line)
return render(request, 'index.html')
2.4 FEV与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会自动根据请求方式的不同匹配类中定义的方法并自动执行
2.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(...)
3. 模板层
3.1 模板语法传值
方式1:指明道姓 指名道姓传参,不浪费资源
def modal(request):
name = 'jason'
age = 18
gender = 'male'
return render(request, 'modal.html', {'name': name, 'age': age, 'gender': gender})
优点:指明道姓的传值,不浪费资源
缺点:数据多的时候,字典需要写好多键值对
方式2:关键字locals() 将整个局部名称空间中的名字去全部传入简单快捷
def modal(request):
name = 'jason'
age = 18
gender = 'male'
return render(request, 'model.html', locals())
优点:将整个局部名称空间中的名字去全部传入简单快捷
缺点:浪费资源
3.2 模板语法传值的范围
1. 基本数据类型直接传递使用
取值点键或点索引,可以连续的点
2. 函数名的传递会自动加括号执行并将返回值展示到页面上
3. 注意函数如果有参数则不会执行也不会展示 模板语法不支持有参函数
4. 类名的传递也会自动加括号产生对象并展示到页面上
5. 对象的传递则直接使用即可
6. 模板语法会判断每一个名字是否可调用,如果可以则调用,django的模板语法在操作容器类型的时候只允许使用句点符.
3.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>
<p>单词截取(空格):{{ s1|truncatewords:6 }}</p>
<p>语法转义:{{ script_tag|safe }}</p>
<p>语法转义:{{ script_tag1|safe }}</p>
from django.utils.safestring import mark_safe
script_tag1 = '<script>alert(666)</script>'
res = mark_safe(script_tag1)
有时候html页面上的数据不一定非要在html页面上编写了 也可以后端写好传入
django模板语法中的符号就两个 一个{{}} 一个{%%}
需要使用数据的时候 {{}}
需要使用方法的时候 {%%}
3.4 模板语法标签(类似于python流程控制)
if
{% if 条件 %} 条件一般是模板语法传过来的数据 直接写名字使用即可
条件成立执行的代码
{% elif 条件1 %}
条件1成立执行的代码
{% else %}
条件都不成立执行的代码
{% endif %}
for
{% for i in s %}
<p>{{ forloop }}</p>
{% endfor %}
{% for i in s %}
{% if forloop.first %}
<p>这是第一次哟~</p>
{% elif forloop.last %}
<p>这是最后一次!</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
{% empty %}
<p>你给我的是个空 怎么for循环呢</p>
{% endfor %}
with
# with起别名
{% with d.hobby.3.info as nb %}
<p>{{ nb }}</p>
在with语法内就可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
<p>{{ d.hobby.3.info }}</p>
{% endwith %}
可以通过as后面的别名快速的使用到前面非常复杂获取数据的方式
取别名后原来的名字也能正常使用
命名规范: 只能在with代码块儿的范围之内才能使用别名
3.5 自定义标签函数、过滤器、inclusion_tag
如果想自定义 必须先做以下三件事
1.在应用下创建一个名为templatetags文件夹
2.在该文件夹创建任意名称的py文件
3.在该py文件内编写自定义相关代码
from django.template import Library
register = Library()
自定义过滤器
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
# 自定义inclusion_tag
@register.inclusion_tag(filename='it.html')
def index(n):
html = []
for i in range(n):
html.append('第%s页'%i)
return locals()
3.6 模板的继承
1. 什么是模板的继承
你需要事先在你想要使用的主页面上划定区域做好标记,之后在子页面继承的时候你就可以使用在主页面划定的区域,也就意味着,如果你不划定任何区域,那么你子页面将无法修改主页面内容
2. 如何使用模板的继承
1.先在你想要继承的主页面上通过bolck划定你将来可能要改的区域,并做好标记
2.在子页面上继承extends,利用block自动提示选取你想要修改的内容区域标记名称
3.在子页面extends中写你要修改主页面标记区的代码
4.然后就可以让子页面的修改内容渲染到主页面的划定区域上
# 模板页面提前先写好将来可能要替换的内容
{% block 名字 %}
"""模板内容"""
{% endblock %}
# 新页面要基于模板页面替换的内容
{% extends 'html文件名' %}
{% block 名字 %}
"""子板内容"""
{% endblock %}
"""一般情况下母板中至少应该有三个区域使得扩展性更高!!! css content js"""
{% block css %}
<style>...</style>
{% endblock %}
{% block content %}
...
{% endblock %}
{% block js %}
<script>...</script>
{% endblock %}
'''子板中还可以使用母板的内容 {{ block.super }} '''
3.7 模板的导入
1.模板导入
将页面的某一个局部当成模块的形式
哪个地方需要就可以直接导入使用即可
2.导入格式
{% include '导入html文件名' %}
分类:
Django框架
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现