今日内容:
模板层(模板语法)标签过滤器自定义标签,过滤器,inclusion_tag模板的继承
模板的导入
首先来说一下render内部原理和FBV与CBV
三板斧 FBV
render返回一个html页面 并且还能够给该页面传数据
render内部原理
from django.template import Template,Context
def index(request):
temp = Template(‘<h1>{{ user }}</h1>‘)
con = Context({"user":{"name":‘jason‘,"password":‘123‘}})
res = temp.render(con)
print(res)
return HttpResponse(res)
FBV与CBV
FBV与CBV 视图函数并不只是指函数,也可以是类 FBV(基于函数的视图)面向函数式编程 CBV(基于类的视图)面向对象式编程 # 问题:基于CBV的视图函数 get请求来就会走类里面的get方法,post请求来就会走类里面post方法,这是为什么了??? #CBV urls.py中 url(r‘^login/‘,views.MyLogin.as_view()) views.py中 from django.views import View
from django.views import View
# from django.conf import settings
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方法")
研究方向:
1.从url入手
View Code
什么settings里面的变量都要用大写的,用小写的没用:
django settings源码
1 django settings源码
2 前提:
3 1.django除了暴露给用户一个settings.py配置文件之外 自己内部还有一个全局的配置文件
4 2.我们在使用配置文件的时候 可以直接直接导入暴露给用户的settings.py也可以使用django全局的配置文件 并且后者居多
5 from django.conf import settings
6 3.django的启动入口是manage.py
7
8 import os
9 import sys
10
11 if __name__ == "__main__":
12 # django在启动的时候 就会往全局的大字典中设置一个键值对 值是暴露给用户的配置文件的路径字符串
13 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
14
15 class Settings(object):
16 def __init__(self, settings_module): # settings_module = ‘day54.settings‘
17 # update this dict from global settings (but only for ALL_CAPS settings)
18 for setting in dir(global_settings): # django全局配置文件
19 # dir获取django全局配置文件中所有的变量名
20 if setting.isupper(): # 判断文件中的变量名是否是大写 如果是大写才会执行/生效
21 setattr(self, setting, getattr(global_settings, setting)) # 给settings对象设置键值对
22 # 给settings对象设置键值对 settings[配置文件中大写的变量名] = 配置文件中大写的变量名所对应的值
23
24 # store the settings module in case someone later cares
25 self.SETTINGS_MODULE = settings_module # ‘day54.settings‘
26
27 mod = importlib.import_module(self.SETTINGS_MODULE) # mod = 模块settings(暴露给用户的配置文件)
28 for setting in dir(mod): # for循环获取暴露给用户的配置文件中所有的变量名
29 if setting.isupper(): # 判断变量名是否是大写
30 setting_value = getattr(mod, setting) # 获取大写的变量名所对应的值
31 setattr(self, setting, setting_value) # 给settings对象设置键值对
32 """
33 d = {}
34 d[‘username‘] = ‘jason‘
35 d[‘username‘] = ‘egon‘
36 用户如果配置了就用用户的
37 用户如果没有配置就用系统默认的
38 其实本质就是利用字典的键存在就是替换的原理 实现了用户配置就用用户的用户没配置就用默认的
39 """
40
41 class LazySettings(LazyObject):
42 def _setup(self, name=None):
43 # os.environ你可以把它看成是一个全局的大字典
44 settings_module = os.environ.get(ENVIRONMENT_VARIABLE) # 从大字典中取值键为DJANGO_SETTINGS_MODULE所对应的值:day54.settings
45 # settings_module = ‘day54.settings‘
46 self._wrapped = Settings(settings_module) # Settings(‘day54.settings‘)
47
48
49 settings = LazySettings() # 单例模式
View Code
模板层
模板语法:一共分为俩大类
{{ }} 跟变量相关的
{%%} 跟逻辑相关的
后端给前端传值的方式:
后端朝前端页面传递数据的方式
# 第一种
return render(request,‘index.html‘,{‘n‘:n})
# 第二种
return render(request,‘index.html‘,locals())
# 将当前所在的名称空间中的名字全部传递给前端页面
后端传函数名到前端,会自动加括号调用,但是不支持传参
详情代码:
前端:
1 <p>{{ n }}</p>
2 <p>{{ f }}</p>
3 <p>{{ s }}</p>
4 <p>{{ l }}</p>
5 <p>{{ d }}</p>
6 <p>{{ t }}</p>
7 <p>{{ se }}</p>
8 <p>{{ index }}</p>
9
10 <p>{{ obj }}</p>
11 <p>{{ obj.get_self }}</p>
12 <p>{{ obj.get_cls }}</p>
13 <p>{{ obj.get_static }}</p>
View Code
后端:
1 def reg(request):
2 # 以下的数据类型都是可以被传递给前端的
3 n = 0
4 # ss = ‘‘
5 f = 1.11
6 s = ‘你妹的‘
7 l = [1, 2, 3, 4, 5, 6]
8 d = {"name": ‘jason‘, ‘password‘: 123}
9 t = (1, 2, 3, 4, 5)
10 se = {1, 2, 3, 4, 5, 6, 7, }
11
12 def index():
13 print(‘index‘)
14
15 class Demo(object):
16 def get_self(self):
17 return ‘绑定给对象的方法‘
18 @classmethod
19 def get_cls(cls):
20 return ‘绑定给类的方法‘
21 @staticmethod
22 def get_static():
23 return ‘我是静态方法 其实就是函数‘
24 obj = Demo()
25
26 # 给模板传值的方式
27 # 方式1 通过字典的键值对方式,然后指名道姓的一个个传
28 # return render(request,‘reg.html‘,{‘n‘:n,‘f‘:f})
29 # 方式2 而用一下locals()会将它所在的名称空间中所有的名字全部传递给前端
30 # 这个方法虽然好用,但是在某些情况下会造成资源的浪费,这里只是为了
31 return render(request,‘reg.html‘,locals())
View Code
模板语法之过滤器:
前端:
|safe
后端:
from django.utils.safestring import mark_safe
zzz = mark_safe(‘<h1>阿萨德搜啊第三款垃圾袋</h1>‘)
<h1>模板语法之过滤器:它内部的原理就是(会将|前面的当做第一个参数传入标签中)</h1>
<p>{{ l|length }} 计算标签内的数据是多长 </p>
<p>{{ n|length }}必须要是放在容器里面才能计算长度</p>
<p>{{ ss|default:‘当|左边的变量为空时,就会返回|右边的值‘}}</p>
<p>{{ file_size|filesizeformat }} 就相当于是一个转换,把kb转为mb</p>
<p>{{ info|truncatewords:3}} 按照空格截取内容的 三个点不算</p>
<p>{{ info|truncatechars:9 }}按字符截取内容的 三个点也算 </p>
<p>{{ xxx|safe }}前端取消转义 </p>
<p>{{ yyy|safe}} 前端取消转义</p>
<p>{{ zzz }} 这个在后端取转义了</p>
<p>{{ time }}</p>
<p>{{ time|date:‘Y-m-d‘ }} 只需要掌握年月日就可以了</p>
<p>{{ n|add:100 }} 做数字相加</p>
<p>{{ s|add:‘大傻叉‘ }} 做字符串拼接</p>
<p>{{ l|slice:‘0:3‘ }}切片取值</p>
<p>{{ l|slice:‘0:5:2‘ }}切片取值</p>
后端详细代码:
1 def reg(request):
2 # 以下的数据类型都是可以被传递给前端的
3 n = 0
4 ss = ‘‘
5 f = 1.11
6 s = ‘你妹的‘
7 l = [1, 2, 3, 4, 5]
8 d = {"name": ‘jason‘, ‘password‘: 123}
9 t = (1, 2, 3, 4, 5)
10 se = {1, 2, 3, 4, 5, 6, 7, }
11 file_size = 12312312
12 info = ‘my name is zy‘
13 xxx = ‘<h1>呃呃呃呃呃</h1>‘
14 yyy = ‘<script>alert(123)</script>‘
15
16 from django.utils.safestring import mark_safe
17 zzz = mark_safe(‘<h1>你是弱智</h1>‘)
18 from datetime import datetime
19 time=datetime.now()
20
21 return render(request,‘reg.html‘,locals())
View Code
模版语法之标签(逻辑相关):
for 循环执行流程图:
# for 循环
{% for s in l %}
<p>{{ forloop }}</p> # forloop可以看到for循环的执行流程
{{ s }}
{% endfor %}
# if else 判断 对象有值就走true 对象为空就走false
{% if ‘‘ %}
<p>xxx条件为true</p>
{% else %}
<p>xxx条件为false</p>
{% endif %}
#for 循环里面可以套if elif else 判断是for循环是否为第一次和最后一次
#如果判断对象为空,就走empty
{% for foo in ‘‘ %}
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次了啊</p>
{% else %}
<p>来啊来啊!!!</p>
{% endif %}
{% empty %}
<p>当for循环的对象为空的时候 会走empty</p>
{% endfor %}
#django模板语法在取值的时候 统一使用句点符(大白话就是 点号 .)
#俩种写法
1.
{{l.6.3.name}}
但是这么写,如果多个地方需要取到的值,太麻烦了
2.
<p>
{% with l.6.3.name as ttt %} 可以给一个比较复杂的取值操作取一个别名 之后在with语句中 就可以使用该别名
{{ ttt }}
{% endwith %}
</p>
# for 循环环也支持循环字典 对象.kyes values items
{% 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 def reg(request):
2 # 以下的数据类型都是可以被传递给前端的
3 n = 0
4 ss = ‘‘
5 f = 1.11
6 s = ‘你妹的‘
7 l = [1,2,3,4,5,6,[12,3,4,{‘name‘:‘heiheihei‘}]]
8 d = {"name": ‘jason‘, ‘password‘: 123}
9 t = (1, 2, 3, 4, 5)
10 se = {1, 2, 3, 4, 5, 6, 7, }
11 file_size = 12312312
12 info = ‘my name is zy‘
13
14
15 return render(request,‘reg.html‘,locals())
View Code
自定义过滤器的使用:
自定义标签 过滤器 inclusion_tag
自定义固定的三步骤(重点)
1.必须在你的应用下新建一个名为templatetags文件夹
2.在该文件夹内新建一个任意名称的py文件
3.在该py文件中固定先写下面俩句代码
from django import template
register = template.Library()
|length |add |default |filesizeformat |truncatewords |truncatechars |safe |slice
自定义过滤器,自定义标签,自定义inclusion_tag:
后端:
# 自定义过滤器
@register.filter(name=‘baby‘)
def index(a,b):
# 这个过滤器只是做一个简单的加法运算
return a + b
前端:
{% load mytage %}
{{ 123|baby:1 }}
注意:
自定义过滤器 只能由两个形参
但是你可以在给第二个参数传值的时候 传一个字符串
只要思想不滑坡
方法总比困难多
{{ 123|baby:‘1|2|3|4|5|6‘}}
自定义标签:
后端:
# 它可以支持传多个值
@register.simple_tag(name=‘zy‘)
def zzz(a,b,c,year):
return ‘%s %s %s %s‘%(a,b,c,year)
前端:
{#支持传多个值,参数与参数之间必须要用空格隔开#}
{% load mytage %}
{% zy 1 2 3 year=5 %}
自定义inclusion_tag:
当你的页面上有一部分html代码需要经常被各个inclusion_tag地方使用 并且需要传参才能渲染出来
那么你可以把该html代码部分制作成一个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}
前端bigplus里面:
<ul>
{% for foo in l %}
<li>{{ foo }}</li>
{% endfor %}
</ul>
前端reg里面:
{% load mytag %}
{% bigplus 5 %}
模板的继承(重点):
当多个页面整体的样式都大差不差的情况下,可以设置一个模板文件,在该模板文件中, 使用block块划分多个区域,之后其他子版要使用模板的时候,可以通过block块的名字, 来选定到底需要修改那一部分区域。
模板一般情况下,应该至少有三个可以被修改的区域
1.
{% block css %}
子页面自己的css代码
{% endblock %}
2.
{% block content %}
子页面自己的html代码
{% endblock %}
3.
{% block js %}
子页面自己的js代码
{% endblock %} 注意:
一般情况下 模板上的block越多,页面的可扩展性就越强
模板的导入:
模板的导入
{% include ‘beautiful.html‘ %}
当你写了一个特别好看的form表单/列表标签等
可以将它当成一个模块 哪个地方需要 就直接导入使用即可
单表操作:
1.单表操作 create_time = models.DateField() 关键性的参数 1.auto_now:每次操作数据 都会自动刷新当前操作的时间 2.auto_now_add:在创建数据的时候 会自动将创建时间记录下来 后续的修改不会影响该字段 ps:在django中 你可以写一个单独测试某一个py文件的测试脚本 不需要再频繁的走web请求
增删改查操作详情:
1 import os
2 import sys
3
4 if __name__ == "__main__":
5 # django在启动的时候 就会往全局的大字典中设置一个键值对 值是暴露给用户的配置文件的路径字符串
6 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day54.settings")
7
8 import django
9 django.setup()
10 from app01 import models
11 models.Book.objects.all()
12 # 增
13 # 方式1: create
14 # book_obj = models.Book.objects.create(title=‘三国‘,price=19.99,create_time=‘2019-11-11‘)
15 # print(book_obj.title)
16 # 方式2:对象点save()方法
17 # from datetime import datetime
18 # ctime = datetime.now()
19 # book_obj = models.Book(title=‘金瓶‘,price=96.66,create_time=ctime)
20 # book_obj.save()
21
22 # 查
23 # print(models.Book.objects.all())
24 # print(models.Book.objects.get(id=1))
25 # print(models.Book.objects.get(pk=1))
26 """
27 pk会自动查找到当前数据的主键字段
28 """
29 # print(models.Book.objects.filter(pk=2))
30
31 # 改
32 # 1.update
33 # models.Book.objects.filter(pk=1).update(title=‘三国演义‘)
34 # 2.对象.save()
35 # book_obj = models.Book.objects.get(pk=1)
36 # book_obj.price = 666.66
37 # book_obj.save()
38
39 # 删除 delete()
40 # models.Book.objects.filter(pk=2).delete()
41
42 # < 1 > all(): 查询所有结果
43
44 # < 2 > filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
45 # < 3 > get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。(源码就去搂一眼~诠释为何只能是一个对象)
46 # < 4 > exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
47 # print(models.Book.objects.exclude(pk=1)) # 只要pk不是1的数据全部查询出来
48
49
50 # < 5 > order_by(*field): 对查询结果排序(‘-id‘) / (‘price‘)
51 # print(models.Book.objects.order_by(‘price‘)) # 默认是升序
52 # print(models.Book.objects.order_by(‘-price‘)) # 加负号就是降序
53
54
55 # < 6 > reverse(): 对查询结果反向排序 >> > 前面要先有排序才能反向
56 # print(models.Book.objects.order_by(‘price‘).reverse())
57
58 # < 7 > count(): 返回数据库中匹配查询(QuerySet)
59 # print(models.Book.objects.count()) # 对查询出来的结果进行一个计数
60
61
62 # 的对象数量。
63 # < 8 > first(): 返回第一条记录
64 # print(models.Book.objects.filter(pk=1).first())
65 # < 9 > last(): 返回最后一条记录
66 # print(models.Book.objects.all())
67 # print(models.Book.objects.all().last())
68
69 # < 10 > exists(): 如果QuerySet包含数据,就返回True,否则返回False
70 # print(models.Book.objects.filter(pk=1000))
71 # print(models.Book.objects.filter(pk=1000).exists())
72
73
74 # < 11 > values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
75 # model的实例化对象,而是一个可迭代的字典序列
76 # print(models.Book.objects.values(‘title‘,‘price‘)) # 得到的结果是列表套字典
77
78
79
80 # < 12 > values_list(*field): 它与values()
81 # print(models.Book.objects.values_list(‘title‘,‘price‘)) # 得到的结果是列表套元组
82
83
84 # 非常相似,它返回的是一个元组序列,values返回的是一个字典序列
85 # < 13 > distinct(): 从返回结果中剔除重复纪录
86 """
87 去重的前提是 一定要有完全重复的数据 才能去重
88 """
89 # print(models.Book.objects.filter(title=‘三国演义‘).distinct())
90 # print(models.Book.objects.values(‘title‘,‘price‘,‘create_time‘).distinct())
View Code
# FBV
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did171622