day54_9_18视图层某内部原理(fbv和cbv)与模板层
一。render内部原理。
在render中往往需要返回三个参数,request,模板和一些键值对。
键值对中存储的是需要对模板渲染的值。
如果手动实现可以如下:
from django.template import Template,Context
def index(request):
temp = Template('<h1>{{ user }}</h1>')
con = Context({"user":{"name":'jason',"password":''}})
res = temp.render(con)
print(res)
return HttpResponse(res)
首先拿到模板,再用render对模板进行渲染,最后使用字符串的形式返回。
二。FBV和CBV
FBV(function base view)
CBV(class base view)
一个是基于函数编写的视图,一个是基于类编写的视图。
对于基于函数编写的就是运行其返回的值,也就是三个渲染模板函数产生的值。
而基于类编写的,需要运行视图函数中的一个内置类函数产生的函数,本质是一个闭包函数。
编写类函数:
from django.views import View
class MyLogin(View):
def get(self,request):
print("from MyLogin get方法")
return render(request,'login.html')
def post(self,request):
return HttpResponse("from MyLogin post方法")
编写url:
url(r'^login/',views.MyLogin.as_view())
可以看到其中需要调用mylogin中运行自己编写的类中的as_view函数。然而这个函数是继承的VIew中的函数。
as_view
as_view是一个绑定类方法的函数。除了正常的异常处理之外,其内部有一个闭包函数,也就是说调用这个函数之后产生的结果就是这个view函数的返回值。
当url匹配成功后,会调用view方法,在view内部返回的是一个使用自定义函数产生的的对象中的dispatch方法(继承父类View的方法)。
也就说dispatch产生的值就是最终返回的值。也就是渲染的页面。dispatch中会首先判断你的请求是否是属于8个基本请求之一。如果是就通过这个字符串和自身定义的类产生的对象,getattr获取对应的函数,最后通过这个函数运行得到渲染的模板返回。
八种请求:
http_method_names =
['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
三。django中settings源码。
对于django中的settings是提供给我们配置文件用的,除了大写的变量之外,其他变量都没有效果,所以其内部会经过独特的处理。
其实,在django框架中有一个全局的配置文件,暴露给用户的settings是很小的一部分,其调用方法如下:
from django.conf import settings
首先介绍os.environ。这相当于一个全局的字典,可以支持字典取值设置值的任何方法。其次介绍dir方法,dir可以将一个模块中的所有变量名取出。
在django启动时,会直接运行manage.py文件,这个文件会先将暴露给用户的settings路径,以变量名:DJANGO_SETTINGS_MODULE为键,加入全局字典中。
在settings方法内部就是一个单例模式,每当调用settings时,会返回一个对象LazySettings()
在LazySettings()内部,首先从全局字典中获取暴露给用户的settings的字符串,将其传给settings方法进行配置。
settings方法首先使用dir方法和for循环获取全局设置中的所有配置,如果是大写就添加到他产生的对象中,也就是调用模块时。
接着再调用用户配置的settings,使用字符串调用模块。同样使用for循环。如果本来的设置中存在就覆盖其值,没有则新建。
也就是说会优先使用用户的设置。
四。模板层之传递值。
当我们使用视图函数向模板传值时,一般都使用字典的方式。
def index(request):
return render(requset,'html',{'名字‘:’数据‘})
然而当有多个值的时侯,单个传值显然很麻烦,通过locals()方法,可以将该函数中的所有参数传递给前端:
def index(request):
return render(request,'reg.html',locals())
虽然locals()方法可以一劳永逸,但是会浪费资源,会传递前端不要的参数。
传入的值如果数python的数据类型几乎都可以被渲染,但是也有特殊的:
1.函数。
如果传函数名,会自动加括号调用该函数,前端展示的是函数调用之后的返回值。
注意:如果函数需要参数的话 那么模板语法不支持。
2.类。
如果将类实例化对象传给前端,会将该对象的内存地址传入,前端页面可以通过该对象名点出其中的函数方法和变量。
其中的函数也不支持传参。
模板语法:
{{}} 变量相关。
{%%}语法相关。
五。模板语法过滤器。
过滤器的固定语法是:
{{ 变量名|过滤器名 }}
其内部原理是,将|前面的变量名当成过滤器的第一个参数传入。
@register.filter(is_safe=False)
def length(value):
"""Returns the length of the value - useful for lists."""
try:
return len(value)
except (ValueError, TypeError):
return 0
如果不支持该过滤器,会返回0
1。{{ l|length }}
统计l的长度。
2。{{ ss|default:'当|左边的变量为空就会返回|右边的值' }}
如果ss存在,则返回ss,如果为空则返回default,如果ss不存在也返回他,和get很像。
3。{{ file_size|filesizeformat }}
将file_size转换成文件大小。
4。{{ info|truncatewords:3 }}
按照空格将info文字进行截断,3是截断的个数。
5。{{ info|truncatechars:6 }}
按照字符截取info,点也算,也就是至少传入3。
6。{{ xxx|safe }}
一般的,xxx字符串传入前端后,直接以字符串的形式传入,但是加上safe之后,就会将xxx按照原来的意思进行输入,如果该字符是页面元素,会显示页面元素。
后端可以取消这个机制:
from django.utils.safestring import mark_safe
zzz=make_safe('内容')
7.{{ ctime|date:'Y-m-d H-i-s' }}
如果后端传来的ctime是一个时间类型的数据,那么可以通过过滤器date进行渲染。
8.{{ n|add:100 }}
将n数字加100,如果是字符串,则拼接字符串。
9.{{ l|slice:'0:5:2' }}
将1切片,故头不顾尾,支持步长
六。模板层之标签。
标签也就是逻辑相关的操作,使用{% %}
1.forloop。
在for循环中,这个标签可以记录for循环的一些值:
{% for foo in l %}
<p>{{ forloop }}</p>
{% endfor %}
如图:
2.{%empty%}
当for 循环为空,则执行这个标签下的方法。
3.if判断:
{% if '' %}
<p>xxx条件为true</p>
{% else %}
<p>xxx条件为false</p>
{% endif %}
4.点。
django模板语法在取值的时候 统一使用句点符。如:
{ l.6.3.name }
5.{%with 数据 as 别名%}
可以通过这个标签给数据取别名,这样可以方便操作。在with中就可以使用该别名。
{% with l.6.3.name as ttt %}
{{ ttt }}
{{ l.6.3.name }}
{% endwith %}
6.for循环中字典的三个方法:
{% for foo in d.keys %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in d.values %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in d.items %}
<p>{{ foo }}</p>
{% endfor %}
七。自定义过滤器与标签。
自定义的东西需要遵循下面三个步骤:
1.必须在你的应用下新建一个名为templatetags文件夹
2.在该文件夹内新建一个任意名称的py文件
3.在该py文件中固定先写下面两句代码
from django import template
register = template.Library()
然后就可以在这个文件下面编写字节的过滤器了:
@register.filter(name='baby')
def index(a,b):
# 该过滤器只做一个加法运算 是|add简易版本
return a + b
定义的时候需要给它取个别名,然后要阿紫网页中调用该过滤器。
{% load mytag %}
{{ 123|baby:1}}
其中mytag是template下的文件名,baby是起的名字。
注意,自定义guolq只能指定两个形参,但是第二个参数可以是一个列表。
自定义标签
标签的定义方法和guolvq差不多:
@register.simple_tag(name='jason')
def xxx(a,b,c,year):
return '%s?%s|%s{%s'%(a,b,c,year)
但是标签支持传入多个参数,标签的使用:
支持传多个参数 参数与参数之间 空格隔开即可、
{% load mytag %}
{% jason 1 2 3 year=2 %}
也支持关键字传参。
自定义inclusion_tag
这个工作原理是接受用户传入的参数,然后根据参数渲染出一个页面,再返回到调用inclusion_tag的地方。
定义方法:
# 自定义inclusion_tag
@register.inclusion_tag('bigplus.html')
def bigplus(n):
l = []
for i in range(n):
l.append('第%s项'%i)
return {'l':l}
它需要指定一个页面,这个页面是要被调用的页面,会接受这个函数返回的值。
调用:
{% load mytag %}
{% bigplus 5 %}
应用场景:
可以定义一个多次运用的页面,可以反复调用。
八。模板的继承和导入。
继承:
当多个页面整体的样式都大差不差的情况下 可以设置一个模板文件。
在该模板文件中 使用block块划分多个预期。
之后子版在使用模板的时候 可以通过block块的名字 来选定到底需要修改哪一部分区域
也就是说,母模板中可以将需要改变的地方通过{% block css%} {% endblock%}划分页面。
{% block css %}
子页面自己的css代码
{% endblock %}
{% block content %}
子页面自己的html代码
{% endblock %}
{% block js %}
子页面自己的js代码
{% endblock %}
这个名字是自己定义的。
在其他页面可以继承这个母模板进行复用:
# 模板的继承 使用方式
{% extends 'home.html' %} {% block css %}
<style>
h1 {
color: red;
}
</style>
{% endblock %}
通过{{ block.super}} 也可以获得目标签该区域的元素
一般情况下 模板上的block越多 页面的可扩展性就越强。
模板的导入:
{% include 'beautiful.html' %}
将一个静态的页面,通过导入的方式加入模板。
九。模型层。
1.单表操作。
create_time = models.DateField()
创建时间的这个参数有关键性的参数。
1.auto_now:每次操作数据 都会自动刷新当前操作的时间
2.auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段
增:
方法1:
book_obj = models.Book.objects.\
create(title='三国',price=19.99,create_time='2019-11-11')
方法2:
方式2:对象点save()方法
from datetime import datetime
ctime = datetime.now()
book_obj = models.Book(title='金',price=96.66,create_time=ctime)
book_obj.save()
查:
models.Book.objects.all()
#查询所有的数据
models.Book.objects.get(id=1)
#按照id查询
models.Book.objects.get(pk=1)
#自动按照主键查询
改:
1.update
models.Book.objects.filter(pk=1).update(title='三国演义')
2.对象.save()
book_obj = models.Book.objects.get(pk=1)
book_obj.price = 666.66
book_obj.save()
删:
删除 delete()
models.Book.objects.filter(pk=2).delete()
其他的函数方法:
(1) all():
查询所有结果
(2)filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
(3)get(**kwargs):
返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
(4)exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
print(models.Book.objects.exclude(pk=1))
# 只要pk不是1的数据全部查询出来
(5) order_by(*field): 对查询结果排序('-id') / ('price')
print(models.Book.objects.order_by('price'))
# 默认是升序
print(models.Book.objects.order_by('-price'))
# 加负号就是降序
(6) reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
print(models.Book.objects.order_by('price').reverse())
(7) count(): 返回数据库中匹配查询(QuerySet)
print(models.Book.objects.count())
# 对查询出来的结果进行一个计数的对象数量。
(8) first(): 返回第一条记录print(models.Book.objects.filter(pk=1).first())
(9) last(): 返回最后一条记录
print(models.Book.objects.all()) print(models.Book.objects.all().last())
(10) exists(): 如果QuerySet包含数据,就返回True,否则返回False
print(models.Book.objects.filter(pk=1000)) print(models.Book.objects.filter(pk=1000).exists())
补充:
1.如果一个类中的函数时绑定类方法,而使用对象调用,会获取对象的类,当成第一个参数传入。
2。通过字符串导入模块的方法:
import importlib
mod = importlib.import_module(从哪个模块中,’所调用的模块的字符串‘)
3.在django中可以写一个单独的test模块进行测试。:
import os
import sys if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
import django
django.setup()
#下面导入模块进行测试。
day54_9_18视图层某内部原理(fbv和cbv)与模板层的更多相关文章
- django中视图处理请求方式(FBV、CBV)
FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV CBV(class base v ...
- Django的View(视图)-settings源码的解析-模板层-模板语法
FBV与CBV 视图函数并不只是指函数,也可以是类 FBV:基于函数的视图,类似面向函数式编程 CBV:基于类的视图,类似面向对象编程 研究解析render源码: render:返回html页面:并且 ...
- Django之视图层与模板层
目录 视图层 小白必会三板斧 HttpResponse render redirect JsonResponse 前后端分离 FBV CBV 给CBV加装饰器 模板层 模板语法 模板传值 过滤器 语法 ...
- (day52)四、视图层、模板层
目录 一.视图层 (一)Request和Response对象 (1)Request对象 (2)Response对象 (二)JsonResponse对象 (1)前后端分离 (2)json_dumps_p ...
- django之视图层和部分模板层
视图层 小白必会三板斧(三个返回的都是HttpResponse对象,通过看源码,可以知道是内部实现) 1.HttpResponse # 返回字符串 2.render # 返回一个html页面 还可以给 ...
- Django基础之视图(views)层、模板层
目录 Django基础之视图(views)层.模板层 JsonResponse 向前端返回一个json格式字符串的两种方式 重写Django中的json的某个方法 form表单上传文件 FBV与CBV ...
- django 之视图层及模板层 04
目录 视图层 render方法是Template和Contex两个对象的组合使用 JsonResponse对象 CBV及源码分析 CBV 加装饰器的方式 模板层 模板语法传值 模板语法 变量 过滤器( ...
- 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 ...
随机推荐
- CodeForces - 1251D (贪心+二分)
题意 https://vjudge.net/problem/CodeForces-1251D 您是一个大型企业的负责人.在您的企业当中共有n位员工为您工作,而且非常有趣的事是这个n是一个奇数(n不能被 ...
- requests---requests请求表单
在做接口测试的时候我们会遇到过需要填写表单的形式,那么如何通过requests进行请求呢? 这里需要引入新的python的第3方库requests-toolbelt requests-toolbelt ...
- Java学习笔记(7)---流(Stream),文件(File)
1.Stream流 a.定义: Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类型.对象.本地化字符集 ...
- 反卷积(Transposed Convolution)
反卷积的具体计算步骤 令图像为 卷积核为 case 1 如果要使输出的尺寸是 5x5,步数 stride=2 ,tensorflow 中的命令为: transpose_conv = tf.nn.con ...
- python通过重启线程,实现服务的热加载
这个思路后来证明不能用于工作. 因为线程调用没有及时返回,所以不能用这种方式来重启服务. 但作为脑洞,也应该作个记录. import os import shutil import datetime ...
- IDEA如何打包可运行jar,外部引用jar包版
背景: 有时候,我们会用IDEA来开发一些小工具,需要打成可运行的JAR包:或者某些项目不是WEB应用,纯粹是后台应用,发布时,也需要打成可运行的JAR包.并且,如果依赖第三方jar时,又不希望第三方 ...
- RNN及其变体框架
RNN及其变体框架 含RNN推导 LSTM理解 理解LSTM网络 算法细节理解及参考文献
- WPF 精修篇 page
原文:WPF 精修篇 page 前言 前段时间看UML 大象 这本书 虽然马上看到了精华片 最后还是暂时暂停 因为这本书 很好 但是暂时对现在的我来说 有点超前 很多东西理解起来还是很难 但是 这本书 ...
- # Spring 练习ioc 、aop
Spring 练习 通过学习spring的基础知识,了解了Spring为了降低Java开发的复杂性,采取了以下4种关键策略: 基于POJO的轻量级和最小侵入性编程: 通过依赖注入和面向接口实现松耦合: ...
- iOpenWorskSDK下载和答疑贴
1 iOpenWorksSDK对VS2013-VS2017的支持插件 https://files.cnblogs.com/files/baihmpgy/iOpenWorksSDK.vsix.zip 2 ...