day52 视图层 模版层
01.视图层
-
小白三板斧
- HttpResponse
- render
- redirect
-
JsonPesponse
-
JsonResponse是HttpResponse的子类,专门用来生成json编码的响应
-
前后端分离
-
前后端通常情况下,通过json的字符串(字典)来进行数据交互
-
后端只需要写好相应的url接口,前端访问这个接口
-
只需要一个 返回一个大字典+开发文档(用来告诉前端工程师这个接口会返回那些数据)即可
-
前后端序列化和反序列化的方法
python后端 js前端 json.dumps() JSON.stringify json.loads() JSON.parse
-
-
向前端发送json字符串
from django.http import JsonResponse dic = {'name':'jason'} # 让不默认转码为ascii # json_str = json.dumps(dic,ensure_ascii=False) return JsonResponse(dic,json_dumps_params={'ensure_ascii':False})
-
JsonResponse是默认序列化字典用的,序列化其他类型需要添加一个safe = False参数
l = [1,2,3,4,5,6,7,] return JsonResponse(l,safe=False)
-
-
FBV与CBV
-
FBV:基于函数的视图
-
CBV:基于类的视图
-
必须要基础View
from django.views import View class MyLogin(View): def get(self, request): return render(request, "add_book.html") def post(self, request): return render(request, 'book_list.html')
-
url.py路由写法
url(r'^login/',views.Mylogin.as_view())
-
CBV源码的实现流程
# 第一步 url(r'^login/',views.Mylogin.as_view()) # url(r'^login/',views.view) 调用as_view()产生了一个闭包函数view
# 第二步 当路由匹配上后执行view函数 return self.dispatch(request, *args, **kwargs) # 调用dispatch函数 http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] def dispatch(self, request, *args, **kwargs): # 判断当前请求方式在不在默认的八个方法内 # 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添加装饰器
-
直接写
@outter # 1.直接写 def get(self, request): print('我是MyLogin里面的get方法') return render(request, 'login.html')
-
推荐写法
-
内部
from django.utils.decorators import method_decorator @method_decorator(outter) # 1.推荐写法 def get(self,request): print('我是MyLogin里面的get方法') return render(request,'login.html')
-
外部
@method_decorator(outter) # 对类内部所用函数添加装饰器 @method_decorator(outter,name='post') # 针对某一功能添加 class MyLogin(View):
-
当要对class内部函数添加一些功能时
@method_decorator(outter) def dispatch(self, request, *args, **kwargs): # 如果你想在视图函数执行之前 做一些操作 你可以在你的CBV中定义dispatch方法来拦截 # 可以在此处对这个类单独做一些操作 return super().dispatch(request,*args,**kwargs)
-
-
-
-
-
django
02.模版层
-
模版语法
{{ }} 变量相关 {% %} 逻辑相关
-
模版语法传值
-
给html的两种方式
-
指名道姓 当需要传递的变量名太多
-
locals
# locals() 会将当前所在的名称空间中所有的名字传递给页面 return render(request, 'test.html', locals())
-
-
能给html传值的数据类型
- 八种基本数据类型都可以
- 函数名:会自动加()调用展示返回值,模版语法不支持函数传参
- 类名:会自动加()产生一个对象
- 对象;可以传递
- 只要是能够加括号调用的,传递到html页面上都会自动加()调用
-
-
过滤器 |
-
模版语法提供了一些内置方法,帮助快速处理数据
-
模版语法
- 会自动将|左边的数据当作过滤器的第一个参数
- 将:右边的当作第二个参数传入
<!--前端--> <p>模板语法之过滤器 会自动将|左边的数据当前过滤器的第一个参数传入 :右边的当做第二个参数</p>
# 后端 from django.utils.safestring import mark_safe sss2 = "<h2>我的h2标签</h2>" res = mark_safe(sss2) # 将字符串变为html内部文本,激活标签
-
过滤器
-
统计长度
<p>统计长度(如果无法统计默认返回0):{{ s|length }}</p>
-
加法运算
<p>加法运算(内部异常捕获 支持数字相加 字符串拼接 都不符合返回空):{{ n|add:f }}</p>
-
切片操作
<p>切片操作 顾头不顾尾 也支持步长:{{ l|slice:'0:5:2' }}</p>
-
自动转成文件大小格式
<p>自动转成文件大小格式:{{ file_size|filesizeformat }}</p>
-
截取文本内容(字符)
<p>截取文本内容(字符) 截取五个字符 三个点也算:{{ s|truncatechars:8 }}</p>
-
截取文本内容(单词)
<p>截取文本内容(按照空格计算) 截取五个单词 三个点不算 :{{ s1|truncatewords:5 }}</p>
-
判断是否有值
<p>判断是否有值(有值展示值本身 没值展示默认值):{{ is_value|default:'is_value变量名指向的值为空' }}</p>
-
展示带有标签的文本
<p>展示带有标签的文本:{{ sss|safe }}</p> <p>默认情况下 是不会自动帮你转换成前端html标签 防止恶意攻击</p>
-
-
标签:逻辑相关的一堆代码
-
for循环,if
<!--for if联合使用--> {% for foo in l %} {% if forloop.first %} <p>这是我的第一次</p> {% elif forloop.last %} <p>这是最后一次了啊</p> {% else %} <p>{{ foo }}</p> {% endif %} {% empty %} <p>当for循环的对象是空的时候会走</p> {% endfor %}
for循环中可用的参数
Variable Description forloop.counter
当前循环的索引值(从1开始) forloop.counter0
当前循环的索引值(从0开始) forloop.revcounter
当前循环的倒序索引值(从1开始) forloop.revcounter0
当前循环的倒序索引值(从0开始) forloop.first
当前循环是不是第一次循环(布尔值) forloop.last
当前循环是不是最后一次循环(布尔值) forloop.parentloop
本层循环的外层循环 -
模版语法的取值只有一种方式,. 句点符
<p>模板语法的取值 只有一种方式 统一采用句点符 (.)</p> <p>{{ comp_dic.hobby.2.2.age }}</p>
-
with 起别名,只能在with内部使用
<p>当你的数据是通过比较复杂的点点点获取到的后续又需要经常使用 你可以给该数据起别名 别名只能在with内部使用</p> {% with comp_dic.hobby.2.2.age as age %} <p>{{ age }}</p> <p>{{ comp_dic.hobby.2.2.age }}</p> {% endwith %}
-
-
自定义过滤器和标签
-
必须要有三步准备
-
在应用名下新建一个templatetags的文件夹
-
在该文件夹内新建一个人一名称的py文件
-
在该文件下写下面的两句话
from django.template import Library register = Library()
-
自定义过滤器
# 自定义过滤器 跟默认的过滤器一样 最多只能接受两个参数 @register.filter(name='baby') def index(a,b): return a + b
<!--自定义过滤器的使用--> <p>自定义过滤器的使用</p> {% load mytag %} <!--要像导入模块一样导入--> {{ 1|baby:1 }} {{ 1|baby:100 }} <!--自定义的过滤器可以在逻辑语句中使用-->
-
自定义标签
# 自定义标签 可以接受任意多个参数 @register.simple_tag(name='mytag') def mytag(a,b,c,d): return '%s?%s?%s?%s'%(a,b,c,d)
<p>自定义标签的使用 可以接受多个参数 参数与参数之间必须空格隔开</p> {% load mytag %} {% mytag 'a' 'b' 'c' 'd' %} {% load mytag %} <!--自定义的标签不能再逻辑语句中使用-->
-
自定义inclusion_tag
- 是一个函数,能给接收外界传入的参数,然后传递给html页面
- 页面上获取数据 渲染 完成之后
- 将渲染好的页面 放到调用 inclusion_tag 的地方
# 自定义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页面
<p>自定义inclusion_tag的使用 当你需要使用一些页面组件的时候 并且该页面组件需要参数才能够正常渲染 你可以考虑使用inclusion_tag</p> {% load mytag %} {% xxx 5 %}
-
-
-
-
模版的继承
-
先在想要继承的页面上通过block划定想要修改的区域 在继承之后就可以使用划定的区域
{% block content %} <!--content为给该区域命名,好在子页面中查找不同的位置--> <!--每个页面不同的地方--> {% endblock %} 先在页面上利用block划定你以后可能想改的区域
<!--继承之后 就可以通过名字找到对应的区域进行修改--> {% extends 'home.html' %} <!--导入要继承的页面--> {% block content %} 修改模板中content区域内容 {% endblock %}
-
模版页面上的block区域越多 页面的可扩展性越强
-
建议一个模版页面最少要有三个block区域
- css区域
- html代码区域,可设置多个block
- js区域
- 有了这三个区域,就能够实现每张页面都能有自己的css和js
{% extends 'home.html' %} <!--导入要继承的页面--> {% block css %} <style> p { color: green; } </style> {% endblock %} {% block content %} <p>login页面</p> <!--你还可以在子页面上继续沿用父页面的内容--> {{ block.super }} <!--可以重复多个--> {{ block.super }} {% endblock %} {% block js %} <script> alert('login') </script> {% endblock %}
-
-
模版的导入
- 将html页面当做模块导入,可以将常用的组件如导航条,页尾信息等保存在单独的文件中
{% include 'bform.html' %}