路由:视图函数的内存地址

视图层

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)

注意事项:

  1. 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。
  2. 如果使用的变量不存在, 模版系统将插入 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之模型层

django 之视图层及模板层 04的更多相关文章

  1. Django基础之视图(views)层、模板层

    目录 Django基础之视图(views)层.模板层 JsonResponse 向前端返回一个json格式字符串的两种方式 重写Django中的json的某个方法 form表单上传文件 FBV与CBV ...

  2. Django-1版本的路由层、Django的视图层和模板层

    一.Django-1版本的路由层(URLconf) URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Dja ...

  3. Django之视图层与模板层

    目录 视图层 小白必会三板斧 HttpResponse render redirect JsonResponse 前后端分离 FBV CBV 给CBV加装饰器 模板层 模板语法 模板传值 过滤器 语法 ...

  4. Django系列(二):Django的路由层,视图层和模板层

    1.Django的路由层 URL配置(URLconf)就像Django所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:我们就是以这种方式告诉Django,对于客户端发来的某 ...

  5. Django 视图层和模板层

    目录 一.网站首页和404页面的路由配置 1. 网站首页路由 2. 404页面 二.Django视图层 1. 小白必会三板斧 (1)HttpResponse (2)render (3)redirect ...

  6. Django的视图层和模板层

    目录 一.视图层 1. 小白必会三板斧 2. JsonResponse 3. FBV与CBV 3.1 FVB 3.2 CBV 4. CBV的源码 5. 给CBV加装饰器 二.模板层 1. 模板语法 2 ...

  7. (day52)四、视图层、模板层

    目录 一.视图层 (一)Request和Response对象 (1)Request对象 (2)Response对象 (二)JsonResponse对象 (1)前后端分离 (2)json_dumps_p ...

  8. Django框架(六)--模板层:变量、过滤器、标签、自定义标签和过滤器

    将页面的设计和Python的代码分离开会更干净简洁更容易维护. 我们可以使用 Django的 模板系统 (Template System)来实现这种模式 # django模板修改的视图函数 def c ...

  9. Django框架(七)—— 模板层:变量、过滤器、标签、自定义标签和过滤器

    目录 模板层:变量.过滤器.标签.自定义标签和过滤器 一.模板层变量 1.语法 2.使用 二.模板层之过滤器 1.语法 2.常用过滤器 3.其他过滤器 三.模板值标签 1.for标签 2.if标签 3 ...

随机推荐

  1. c++ | final

    C++11的关键字final有两个用途:(1).禁止虚函数被重写:(2).禁止基类被继承. 在派生类中,可以同时使用overried和final.

  2. 递归拷贝目录与删除目录 WindowsAPI C++

    /*判断一个路径是否是已存在的目录*/ bool IsDirectory(const std::wstring& pstrPath) { DWORD dw = GetFileAttribute ...

  3. sql server备份损坏

    sql server备份损坏 转自:https://www.cnblogs.com/zhijianliutang/p/4080916.html 1.备份文件和数据库放在同一个(或一组)的物理磁盘上.磁 ...

  4. Robot Framework-失败用例自动重跑

    使用自动化脚本进行测试,经常受环境影响等各方面导致本能成功的脚本失败,下面介绍了RFS框架下,失败重跑的方法: 通过改写RobotFramework源代码增加–retry选项,实现test级别的失败用 ...

  5. 什么是云数据库RDS PPAS 版

    云数据库PPAS版,是阿里云与EnterpriseDB公司合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL.数据类型.高级函数 ...

  6. 友善的树形DP

    一棵树,如果有序点对(x,y)之间路径的长度取模于3==0,那么ans0便加上这个长度: 如果取模于3==1,那么ans1便加上这个长度: 如果取模于3==2,那么ans2便加上这个长度: 让你求an ...

  7. PHP与MySQL的连接

    一.PHP的相关扩展 PHP与MySQL的交互需要要借助PHP提供的数据库扩展,在PHP中提供了多种数据库扩展,常用的MySQL扩展, MySQLi扩展和PDO扩展. 1.三者各自的特点: MySQL ...

  8. 一、redis学习(基础)

    redis  持久化 rdb aof 

  9. LintCode 64---合并排序数组

    public class Solution { /* * @param A: sorted integer array A which has m elements, but size of A is ...

  10. springboot配置文件之yml的语法学习

    springboot配置文件(.yml/.yaml.properties) YAML(YAML Ain't Markup Language) YAML A Markup Language:是一个标记语 ...