MVC:
M: model 模型 操作数据库
V: view 视图 展示页面 HTML
C: controller 控制器 调度 业务逻辑
MTV:
M: model 模型 操作数据库 ORM
T: template 模板 HTML
V: view 视图 业务逻辑 url路由
变量
{{ 变量名 }}
{{ 变量名. }} #索引,key,属性,方法
过滤器 : 用来修改变量的显示结果
内置过滤器
#语法: {{ value|filter_name:参数 }} #':'左右不能有空格 1.default找不到变量时的默认值 {{ value|default:'默认值' }} #value变量不存在或者为空的时候显示默认值 #在settings文件中的 TEMPLATES(模板) 的OPTIONS可以增加一项 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], 'string_if_invalid':'找不到' #可以替代default的作用 }, }, ] 2.filesizeformat把数字转换成文件大小 #变量filesize = 1024 1表示1byts {{ filesize|filesizeformat }} #结果为 1kb 3.add变量相加(数字相加,字符串拼接,列表拼接) st='1' st1=2 a=[1,2,'3'] b=[4,5,'6'] {{ st|add:st1 }} #3 {{ st|add:'2' }} #4 {{ st|add:'str' }} #1str {{ a|add:b }} #[1, 2, '3', 4, 5, '6'] #如果元素是2个数字add,不管是数字类型的还是字符串类型的都转换为数字进行相加 4.upper/lower大小写转换 a = 'aBc' {{ a|upper }} #’ABC‘ {{ a|lower }} #'abc' 5.title标题首字母大写 b = 'biT hello' {{ b|title }} #’Bit Hello‘ 6.length变量的长度 a='123456789000' li=[1,2,3,4,5,6] b=12345679000 dic={'1':11,'2':22,'3':33} st0='你好' {{ a|length}} #12 {{ li|length }} #6 {{ b|length }} #0 {{ dic|length }} #3 {{ st0|length }} #2 7.silce切片 st='0123456' {{ st|slice:'1:3'}}<br> #12 {{ st|slice:':3'}}<br> #012 {{ st|slice:'2:'}}<br> #23456 {{ st|slice:'1:-2'}}<br> #1234 {{ st|slice:'-2:1:-1'}}<br> #5432 {{ st|slice:'1:-1:-1'}}<br> #空 {{ st|slice:'5:-5:-1'}}<br> #543 #方向与切片方向不同时不显示 #只能用于有序列表,无序不可切片 8.filst/last第一和最后 st='0123456' {{ li|first }} 1 {{ li|last }} 6 #只能用于有序对象,字符串。列表,元祖 #集合获取不到,字典报错 9.join字符串拼接 li=[1,2,3] {{ li|join:'-' }} #1-2-3-4-5-6 10.truncatechars截断字符串,被截的字符串显示(...),并且占据设置长度的三个字符(如果设置小于等于3那么只显示...) a0='壹贰叁肆伍陆柒捌玖' {{ a0|truncatechars:'5' }} #壹贰... 11.truncatewords对英文单词进行截断(不支持中文,但是支持空格)保留单词个数加... value = "Joel is a slug" {{ value|truncatewords:2 }} # Joel is ... 12.日期格式化 {{ now|date:'Y-m-d H:i:s' }} #年月日时分秒 #或者settings中配置 USE_L10N = False DATETIME_FORMAT = 'Y-m-d H:i:s' 13.safe 告诉django不需要转义(防止跨站攻击) js = '<a href="http://www.baidu.com">跳转</a>' {{ js|safe }} #或者py文件中 from django.utils.safestring import mark_safe 'a':mark_safe('<a href="http://www.baidu.com">跳转</a>') {{ a }}
自定义过滤器
1.在app下创建一个名为templatetags的python包 2.在包内创建py文件(名字随便取) 3.在py文件中写入: from django import template register = template.Library() #register是固定名字不能变 4.定义函数加装饰器 @register.filter def new_upper(value,arg=None): #自定义过滤器最多传一个arg参数 return value + arg 5.在模板中使用: {% load my_tags %} {{ 'asd'|new_upper:string }}
for循环的基本格式和参数
#基本格式 {% for i in list %} {{ i }} {{ i.xx }} # xx 可以是属性,方法,对象 {% endfor %} # for循环自带的forloop参数 {{ forloop.counter }} #从1开始循环计数 {{ forloop.counter0 }} #从0开始循环计数 {{ forloop.revcounter }} #倒序循环计数,到1结束 {{ forloop.revcounter0 }} #倒序循环计数,到0结束 {{ forloop.first }} #判断当前循环是不是第一次循环,返回bool值 {{ forloop.last }} #判断当前循环是不是最后一次循环,返回bool值 {{ forloop.parentloop }} #嵌套循环时,本循环的父循环 # for empty 如果值不存在或者为空则显示empty中的内容 <ul> {% for book in all_books %} <li>{{ book.bane }}</li> {% empty %} <li>'对不起,值为空'</li> {% endfor %} </ul> #相当于 <ul> {% if athlete_list %} {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} {% else %} <li>Sorry, no athletes in this list.</li> {% endif %} </ul>
if判断
支持 and, or, ==, >, <, <=, >=, in, not in, is, is not判断 不支持 连续判断, 算数运算 支持连续的逻辑运算(not,and,or) #如果需要算数运算的时候用过滤器 {% if messages|length >= 100 %} You have lots of messages today! {% endif %} #连续逻辑运算 {% if athlete_list and coach_list %} Both athletes and coaches are available. {% endif %} {% if not athlete_list %} There are no athletes. {% endif %} {% if athlete_list or coach_list %} There are some athletes or some coaches. {% endif %} {% if not athlete_list or coach_list %} There are no athletes or there are some coaches. {% endif %} {% if athlete_list and not coach_list %} There are some athletes and absolutely no coaches. {% endif %}
with取别名
{% with hobby_list.2.3 as new %} #给复杂的变量取别名以后方便调用 {{ nwe }} {% endwith %} #别名的使用必须写在with和endwith之内
csrf_token 防止跨站请求(跨站请求伪造保护)
跨站请求:在a网站(钓鱼网站)获取表单,提交表单action地址指向b网站,(表单内容被a网站提交过程中修改然后再发给b网站)
csrf作用:在b网站请求表单,action地址也指向b网站,在网站请求表单时带有标记,b接受表单执行csrf验证,如果与b网站保存的标记不同,csrf直接拒绝(Forbidden (403),CSRF verification failed. Request aborted.)
form 标签的表单中添加一个影藏的input标签里面自带name和value用于提交验证
注释
<!-- 在html渲染时不显示,但是可以在body中看到 --> 前端页面提示
{# 在代码中注释,在body中也看不到 #} 直接取消代码任何效果
母版继承
母板:HTML页面,提取多个页面的公共部分
block块:母板中预留出可以被继承其的子HTML文件替换(变更)的地方,每个block块都要用不同的名字来命名
{% block page-main %}
<p>世情薄</p>
<p>人情恶</p>
<p>雨送黄昏花易落</p>
{% endblock %}
继承: 在子文件的最上面加上 {% entends '母板文件名' %},然后重写block块,
{% extends '母版名.html' %} #必须写在第一行,否则前面有内容会被显示
#直接写‘母版名.html’必须加引号,不加引号当作变量查找,这需要先把字符串传值给变量
#重写block块 --
{% block 块名字 %}
(子页面独特的内容)
{% endblock %}
#要显示的内容必须写在block快中
#多定义block快,每个页面独立设置自己的(先用block块命名在母板定义占位,在继承中可以引用block同名来修改内容
通常会在母板中定义页面专用的CSS块和JS块(空block占位),方便子页面(在正确的占位处写代码)替换。省去重写模板中公共代码,只要继承导入母版页面骨架
组件 include
具有独立功能的固定不变一小段代码,如导航栏,左侧菜单栏
#可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可
{% include '组件.html' %}
静态文件相关
#引入方式一: <link rel="stylesheet" href="/static/css/dashboard.css/"> #引入方式二: {% load static %} <link rel="stylesheet" href="{% static 'css/dashboard.css' %}"> {% get_static_prefix %} #settings中配置任何别名都能找到 #引入方式三: {% load static %} <link rel="stylesheet" href="{% get_static_prefix %} css/dashboard.css"> {% get_static_prefix %} #settings中配置任何别名都能找到 #引入方式四: {% load static %} {% get_static_prefix as STATIC_PREFIX %} <link rel="stylesheet" src="{{ STATIC_PREFIX }}css/dashboard.css" />
自定义标签simple_tag
自定义标签和自定义过滤器差不多,但是能传任意个数的参数用起来更加灵活,但是标签不支持嵌套(弊端)
#步骤
1.在已注册的app下创建一个templatetags的python包 2.在包中创建文件(随便取名) 3.在文件中引入 from django import template register = template.Library() 4.自定义函数加装饰器 @register.simple_tag def join_str(*arg,**kwargs): #可以接受任意数量参数 函数体(具体操作) return 返回值(显示到页面的内容) 5.模板中使用 {% load 自定义标签文件名 %} {% join_str '1' '2' k1='3' k2='4' %} #直接使用函数,空格间隔传参
inclusion_tag
一般用于返回动态的组件(html代码段)
1.在一处侧的app下创建templatetags文件夹 2.自定义一个文件 3.引入 from django import template register = template.Library() 4.自定义函数(装饰器返回字典参数给'需要渲染.html') @register.inclusion_tag('渲染页面.html') def func(*args,**kwargs): 函数体 return {返回给页面渲染} 5.在渲染样式的html页面对标签传回字典加工并显示结果(for,if) 6.在使用页面导入自定义文件名 {% load my_tags %} {% func 参数 参数 %} #导入函数并传参,进过html渲染,把页面结果展示出来
例子(动态分页功能):
页面显示分页效果: 1.自定义函数代码在my_tags.py from django import template register = template.Library() @register.inclusion_tag('page.html') def page(num): return {'num': range(1, num + 1)} 2.中间页page.html <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {% for i in num %} <li><a href="#">{{ i }}</a></li> {% endfor %} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> 3.使用页面调用 {% load my_tags %} {% page 2 %}