django 之视图层及模板层 04
路由:视图函数的内存地址
视图层
render方法是Template和Contex两个对象的组合使用
from django .template import Template,Context
def func1(request):
res = Template('<h1>{{user}}</h>')
con=Context({'user':{'username':'zhang','password':123,}})
return HttpResponse(res.render(con))
JsonResponse对象
JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
# ensure_ascii=False 默认等于True,设置成False,遇到中文不再进行转码,仅仅只是进行序列化,转换成json形式的字符串
import json
def func(request):
d={'a':1,'b':3,'c':3,'d':4,'e':'速度发货!!!!!!!'}
return HttpResponse(json.dumps(d,ensure_ascii=False),) #
from django.http import JsonResponse
def func(request):
d={'a':1,'b':3,'c':3,'d':4,'e':'速度发货!!!!!!!'}
l=[1,2,3,4,5,]
# return JsonResponse(d) # 加括号是个对象,内部也是基于json.dumps进行的序列化,默认遇到中文也会转成ASCII编码,
# return JsonResponse(d,json_dumps_params={'ensure_ascii':False}) # 遇到中文不转码
return JsonResponse(l,safe=False) # In order to allow non-dict objects to be serialized set the safe parameter to False. 根据报错信息,去源码找到JsonResponse不能序列化其他数据类型的原因,就是修改safe=True 为False,之后就能序列化其他数据类型(json模块能序列化的)了
CBV及源码分析
我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的。
FBV:基于函数的视图
CBV:基于类的视图
from django.views import View
class MyLogin(View):
def get(self,request):
print('我是MyLogin里面的get方法')
return render(request,'login.html')
def post(self,request):
print('我是MyLogin里面的post方法')
return HttpResponse('post')
# 路由的书写 与CBV有点不同
# FBV写法 路由 >>> 视图函数内存地址
url(r'^index/',views.index),
# CBV写法
url(r'^login/',views.MyLogin.as_view()) # views.view 本质也是FBV
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
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 http.HttpResponseNotAllowed(self._allowed_methods())
@classonlymethod
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs): # 闭包函数
self = cls(**initkwargs) # cls是我们自己写的类 MyLogin self是我们自己定义的类的对象
# 在看源码的时候 你一定要把握住一个顺序 对象在查找属性和方法的时候
# 先从对象自身找 再去产生对象的类中找 再去类的父类中找
return self.dispatch(request, *args, **kwargs)
return view
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
# 判断当前请求方式在不在默认的八个方法内
# 1.先以GET请求为例
if request.method.lower() in self.http_method_names:
# 利用反射去我们自己定义类的对象中查找get属性或者是方法 getattr(obj,'get')
# handler = 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方法
CBV 加装饰器的方式
使用装饰器装饰FBV
FBV本身就是一个函数,所以和给普通的函数加装饰器无差:
def wrapper(func):
def inner(*args, **kwargs):
start_time = time.time()
ret = func(*args, **kwargs)
end_time = time.time()
print("used:", end_time-start_time)
return ret
return inner
# FBV版添加班级
@wrapper
def add_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "add_class.html")
CBV 加装饰器的方式
类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。
Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器
#使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。
给CBV加装饰器 推荐你使用内置模块
from django.utils.decorators import method_decorator
# 2.可以指定给谁装
# @method_decorator(wrapper,name='post') # name=... 表示指定给谁装
# @method_decorator(wrapper,name='dispatch')
class MyLogin(View):
@method_decorator(wrapper)
def dispatch(self, request, *args, **kwargs): # 如果你想在视图函数执行之前 做一些操作 你可以在你的CBV中定义dispatch方法来拦截
return super().dispatch(request,*args,**kwargs)
# @outter # 1.直接写
# @method_decorator(outter) # 1.推荐写法
def get(self,request):
print('我是MyLogin里面的get方法')
return render(request,'login.html')
# @outter
def post(self,request):
print('我是MyLogin里面的post方法')
time.sleep(1)
return HttpResponse('post')
模板层
模板语法传值
模板语法
只有两种书写格式:
{{}} 变量相关
{%%} 逻辑相关
模板传值:python基本数据类型全部支持传值
变量
在Django的模板语言中按此语法使用:{{ 变量名 }}。
当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。
点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询:
字典查询(Dictionary lookup)
属性或方法查询(Attribute or method lookup)
数字索引查询(Numeric index lookup)
注意事项:
- 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
- 如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为'' (空字符串)
# test.py文件
def test(request):
n=1
f=1.11
s='hello baby~'
l=[1,2,3,4,]
t=(1,2,3,44,55)
d={'name':'zhangsan','hobby':'read'}
se={12,13,14,15,}
b=False
def index1(): #给HTML页面传递函数名的时候 模板语法会自动加括号调用该函数 并且将函数的返回值当做展示依据,模板语法不支持函数传参 也就意味着 你传给html页面的只能是不需要传参调用的函数
return '都是废话'
class Test(object):
def get_self(self):
return 'get_self'
obj = Test()
return render(request,'test.html',locals())
# 传类名像函数名一样,也是加括号调用,实例化一个对象;传对象,就是对象本身,是类的对象的内存地址;只要是能够加括号调用的 传递到html页面上都会自动加括号调用
<!--test.html文件-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<p>{{ n }}</p>
<p>{{ f }}</p>
<p>{{ s }}</p>
<p>{{ l }}</p>
<p>{{ se }}</p>
<p>{{ d }}</p>
<p>{{ b }}</p>
<p>传函数名:{{ index1 }}</p>
<p>传函数名:{{ Test }}</p>
<p>传函数名:{{ obj }}</p>
</body>
</html>
过滤器(Filters)
模板语法也给你提供了一些内置的方法 帮你快速的处理数据
过滤器的语法: {{ value|filter_name:参数 }}
例如:{{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。
注意事项:
1.过滤器支持“链式”操作。即一个过滤器的输出作为另一个过滤器的输入。
2.过滤器可以接受参数,例如:{{ sss|truncatewords:30 }},这将显示sss的前30个词。
3.过滤器参数包含空格的话,必须用引号包裹起来。比如使用逗号和空格去连接一个列表中的元素,如:{{ list|join:', ' }}
4.'|'左右没有空格没有空格没有空格
前后端取消转义(*)
前端
|safe
后端
from django.utils.safestring import mark_safe
sss2 = "<h2>我的h2标签</h2>"
res = mark_safe(sss2)
<p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>
<p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>
<p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>
<p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>
<p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>
<p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>
<p>截取文本内容(按照空格计算) 截取五个字符 三个点不算 :{{ s1|truncatewords:5 }}</p>
<p>默认情况下,不会转换成前端html标签 :{{sss}}</p> # 后端传来的字符串类型的标签
<p>展示带有标签的文本:{{ sss|safe }}</p> 添加safe参数之后可以转换后端传来的字符串标签
<p>展示带有标签的文本:{{ ss|safe }}</p> 后端: ss='<script>alert(123)</script>'
标签
标签 逻辑相关
if
for循环
{% for foo in l %}
{{ forloop }}
{% if forloop.first %}
<p>{{ foo }}</p>
{% elif forloop.last %}
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>档for循环的对象为空的时候走这个!</p>
{% endfor %}
模板语法的取值 只有一种方式 统一采用句点符 (.)
{{ comp_dic.hobby.2.2.age }}
<p>当你的数据是通过比较复杂的点点点获取到的后续又需要经常使用 你可以给该数据起别名 别名只能在with内部使用</p>
{% with comp_dic.hobby.2.2.age as age %}
<p>{{ age }}</p>
<p>{{ comp_dic.hobby.2.2.age }}</p>
{% endwith %}
自定义过滤器和标签
自定义过滤器
django支持用户自定义
必须要先有三部准备
1.在应用名下新建一个名字必须叫templatetags的文件夹
2.在该文件夹内 新建一个任意名称的py文件
3.在该py文件中 必须先写下面两句代码
from django.template import Library
register = Library()
之后就可以利用register来自定义过滤器和标签
# 应用名下templatetag文件夹 mytag.py文件
from django.template import Library
register = Library()
# 自定义过滤器,跟默认的过滤器一样,最多只能接受两个参数
@register.filter(name='xxx') # 给过滤器起名字
def index(a,b):
return a+b
使用自定义的过滤器,需要先在html页面上 加载。
<!--test.html文件-->
{% load mytag %}
{{ 1|xxx:99 }}
自定义标签
# 应用名下templatetag文件夹 mytag.py文件
# 自定义标签 可以接受任意多个参数
@register.simple_tag(name='zzz')
def mytag(a,b,c,d):
return '%s?%s?%s?%s'%(a,b,c,d)
<!--test.html文件-->
{% load mytag %}
{% zzz 'a' 'b' 'c' 'd' %}
<!--test.html文件-->
<p>自定义的过滤器可以在逻辑语句使用 而自定义的标签不可以</p>
{% if 1|xxx:99 %}
<p>有值</p>
{% else %}
<p>无值</p>
{% endif %}
自定义inclusion_tag
是一个函数 能够接受外界传入的参数, 然后传递给一个html页面,页面上获取数据 渲染完成之后,将渲染好的页面放到调用inclusion_tag的地方
# 应用名下templatetag文件夹 mytag.py文件
# 自定义inclusion_tag
@register.inclusion_tag('mytag.html',name='xxx')
def index666(n):
l = []
for i in range(n):
l.append('第%s项'%i)
return locals() # 将l直接传递给mytag.html页面
<!--mytag.html文件-->
<!--只做临时渲染的页面,所以该页面的其他框架部分html代码就不需要了-->
<ul>
{% for foo in l %}
<li>{{ foo }}</li>
{% endfor %}
</ul>
<!--test.html文件-->
<p>自定义inclusion_tag的使用 当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag</p>
{% load mytag %}
{% xxx 5 %}
模板的继承
你需要事先在你想要使用的页面上划定区域,之后在继承的时候 ,你就可以使用你划定的区域,也就意味着,如果你不划定任何区域,那么你将无法修改页面内容。
<!--先在页面上利用block划定你以后可能想改的区域-->
{% block content %}
{% endblock %}
<!--继承之后 就可以通过名字找到对应的区域进行修改-->
{% extends 'home.html' %}
{% block content %}
<!--修改模板中content区域内容-->
{% endblock %}
模板上的block区域越多 页面的扩展性越强
建议你一个模板页面至少有三块区域:
css区域
html代码区域 可以设置多个block
js区域
有了这三块区域 就能够实现每一个页面都有自己独立的css和js代码
{% extends 'home.html' %} 子文件就可以通过这个方法继承猪文件的html代码的格式
{% block css %}
<style>
p {
color: green;
}
</style>
{% endblock %}
{% block content %}
<p>login页面</p>
{% endblock %}
{% block js %}
<script>
alert('login')
</script>
{% endblock %}
你还可以在子页面上继续沿用父页面的内容
{{ block.super }}
模板的继承
1.先在你想要继承的页面上通过block划定你将来可能要改的区域
2.在子页面上先继承extends
3.利用block自动提示 选择你想要修改的内容区域
模板的导入
将html页面当做模块的直接导入使用
{% include 'bform.html' %}
django 之视图层及模板层 04的更多相关文章
- Django基础之视图(views)层、模板层
目录 Django基础之视图(views)层.模板层 JsonResponse 向前端返回一个json格式字符串的两种方式 重写Django中的json的某个方法 form表单上传文件 FBV与CBV ...
- Django-1版本的路由层、Django的视图层和模板层
一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...
- Django之视图层与模板层
目录 视图层 小白必会三板斧 HttpResponse render redirect JsonResponse 前后端分离 FBV CBV 给CBV加装饰器 模板层 模板语法 模板传值 过滤器 语法 ...
- Django系列(二):Django的路由层,视图层和模板层
1.Django的路由层 URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Django,对于客户端发来的某 ...
- Django 视图层和模板层
目录 一.网站首页和404页面的路由配置 1. 网站首页路由 2. 404页面 二.Django视图层 1. 小白必会三板斧 (1)HttpResponse (2)render (3)redirect ...
- Django的视图层和模板层
目录 一.视图层 1. 小白必会三板斧 2. JsonResponse 3. FBV与CBV 3.1 FVB 3.2 CBV 4. CBV的源码 5. 给CBV加装饰器 二.模板层 1. 模板语法 2 ...
- (day52)四、视图层、模板层
目录 一.视图层 (一)Request和Response对象 (1)Request对象 (2)Response对象 (二)JsonResponse对象 (1)前后端分离 (2)json_dumps_p ...
- Django框架(六)--模板层:变量、过滤器、标签、自定义标签和过滤器
将页面的设计和Python的代码分离开会更干净简洁更容易维护. 我们可以使用 Django的 模板系统 (Template System)来实现这种模式 # django模板修改的视图函数 def c ...
- Django框架(七)—— 模板层:变量、过滤器、标签、自定义标签和过滤器
目录 模板层:变量.过滤器.标签.自定义标签和过滤器 一.模板层变量 1.语法 2.使用 二.模板层之过滤器 1.语法 2.常用过滤器 3.其他过滤器 三.模板值标签 1.for标签 2.if标签 3 ...
随机推荐
- Linux批量文件管理
Linux批量文件管理 实验目标: 通过本实验掌握批量建立.移动.复制文件或目录的操作,也可以作为后续shell编程的基础. 实验步骤: 1.现在有十台终端机器,要为每台机器建立3个文件,总共要建 ...
- 服务器iptables规则记录
很多时候,我在我自己的VPS上面部署了Cobalt Strike,可是网上很多叼毛就会扫描我们的VPS,然后发现我们的Cobalt Strike,如果你还建有web delivery,还会被人家下载上 ...
- Win10黑色白色主题切换
打开设置面板 选择个性化 -> 颜色 -> 选择默认应用模式 然后选择亮和暗就好了. (这还是看404说的我才知道.)
- flask_script
Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行任 ...
- C语言|作业12—学期总结
一. 我学到的内容 二. 我的收获 作业链接 收获 C语言l博客作业01 对这个专业.学科以及markdown语法有了初步了解,打印出了"Hello world!" C语言l博客作 ...
- [ZJOI2007]捉迷藏(动态点分治/(括号序列)(线段树))
题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条 ...
- 使用javascript完成一个简单工厂设计模式。
在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...
- java-selenium三种等待方式
方式1: 线程等待:Thread.sleep(xxxx) 只要在case中加入sleep就会强制等待设置的时间后才会执行之后的命令,这种等待一般适用于调试脚本的时候. java代码 //等待3秒 Th ...
- .Net Core控制台应用加载读取Json配置文件
⒈添加依赖 Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.FileExtensions Microsoft ...
- 【一道来自老师的题的题解】equip——奇妙的最短路
这道题真的第一眼完全想不到是最短路啊!!!!!!!! 感谢DR大佬讲解!!!!!90°鞠躬 =u= 暂时没有评测网址,(因为需要special judge)敬请期待 机房另一大佬JYY题解,可以对比参 ...