模板层之标签

模板语法支持if判断(支持elif):

{% if 条件1(可以自己写也可以用传递过来的数据) %}
<p>今天又是周三了</p>
{% elif 条件2(可以自己写也可以用传递过来的数据) %}
<p>百日冲刺</p>
{% else %}
<p>没多少时间了!</p>
{% endif %}

模板语法支持for循环,有一个特殊的关键字forloop:



first 键只有在是第一次循环时才是True

last 键只有在是最后一次循环时才是false

counter0 从0开始计数

counter 从1开始计数

for循环的示例:

{% for k in t1 %}
{% if forloop.first %}
<p>这是我的第一次循环{{ k }}</p>
{% elif forloop.last %}
<p>这是我的最后一次循环{{ k }}</p>
{% else %}
<p>这是中间循环{{ k }}</p>
{% endif %} {% empty %}
<p>你给我传的数据是空的无法循环取值(空字符串、空列表、空字典)</p>
{% endfor %}



结果:



for循环的empty分支:

如果传的数据支持for循环,但是里面没有数据值,这时候会走empty分支。



写前后端分离项目时,不会使用模板语法。

django模板语法取值操作 >>> 只支持句点符

django模板语法取值操作>>>:只支持句点符
句点符既可以点索引也可以点键
{{ d1.hobby.2.a1 }}

示例:



对于这种字典套列表的数据,可以这样取值:



也就是说,以点的方式取值既可以点索引也可以点键。django会自己取去判断点的后面是索引还是键。

如果对象中的某个值要多次使用:

可以取别名:

{% with d1.hobby.2.a1 as h %}
<a href="">{{ h }}</a>
{% endwith %}



只有在with代码块之内可以使用as取的别名。

自定义模板语法

快速浏览

'''
1.在应用下创建一个templatetags目录
2.在上述目录下创建任意名称的py文件
3.在上述py文件内先编写两行固定的代码
from django import template
register = template.Library() html文件上需要提前加载才可以使用
{% load py文件名 %}
过滤器
标签
inclusion_tag
'''
1.过滤器(数据|过滤器名:参数)
@register.filter(name='过滤器名称')
def func(a, b):return a + b 2.标签
@register.simple_tag(name='标签名')
def index(*args):return 123 3.inclusion_tag
@register.inclustion_tag(file_name='html文件名',name='名称')
def foo(*args):return locals()

前期准备

如果想要自定义一些模板语法 需要先完成下列的三步:

  1. 在应用下创建一个名字必须叫templatetags的目录
  2. 在上述目录下创建任意名称的py文件
  3. 在上述py文件内先编写两行固定的代码
from django import template
register = template.Library()

自定义过滤器

# 自定义过滤器(最大只能接收两个参数)
@register.filter(name='myadd')
def func1(a, b):
return a + b
{% load mytags %}
<p>{{ i|myadd:1 }}</p>

django过滤器最大只能接受两个参数

在py文件下自定义过滤器:



用之前需要加载过滤器:

自定义标签

相当于自定义函数,其参数没有限制

# 自定义标签(参数没有限制)
@register.simple_tag(name='mytag')
def func2(a, b, c, d, e):
return f'{a}-{b}-{c}-{d}-{e}'
{% load mytags %}
{% mytag 'jason' 'kevin' 'oscar' 'tony' 'lili' %}



支持传多个参数:

自定义inclusion_tag

首先我们要事先在templatetags下的py文件定义好一个函数:

# 自定义inclusion_tag(局部的html代码)
@register.inclusion_tag('menu.html',name='mymenu')
def func3(n):
html = []
for i in range(n):
html.append('<li>第%s页</li>'%i)
return locals()

menu.html:我们函数的返回值将会输入到这个html文件中。这个html不是完整的html,只包含一部分标签,可以理解成一个小组件。

name='mymenu':这是我们定义的inclusion_tag的名字,可以通过这个名字,调用函数func3。

menu.html内部代码:



menu.html接受到func3传来的列表:

['<li>第1页</li>','<li>第2页</li>','<li>第3页</li>','<li>第4页</li>','<li>第5页</li>'....]

使用过滤器{{ liStr|safe }},将字符串变成真的html代码。

最后传递到原html页面使用,还可以指定参数(这个参数对应函数形参n):



效果:

模板的继承与导入

快速浏览

1.模板的继承
模板上划定将来可以修改的区域
block 区域名称
子板上通过申明区域名称修改内容
{% extends '模板名称' %}
block 区域名称
block.super
ps:模板中至少应该有三个区域(css区域、内容区域、js区域) 2.模板的导入
{% include '局部html文件' %}

引入

我们经常可以看到这样的网站:



点击登录--->导航条 和 侧边栏不变 右边变成登录的页面

也就是说页面中有固定不动的部分和动态变化的部分。

多个页面有很多相似的地方 我们可以采取下列方式:

方式1:传统的复制粘贴

方式2:模板的继承

模板的继承

模板的继承只需要一行模板语法就可以做到。

假如home.html是我们的母模板,则先将子板的html代码清空,再加入代码:

{% extends 'home.html' %}

就可以实现继承。

划定子板可修改的区域 block

django模板语法支持在继承的前提上修改,这时候需要在母板上提示哪些部分可以修改:



语法:{% block 区域名称 %}

注意这里的content只是个名字,可以自行修改。

继承页可以修改content代码块的内容:



继承页在content编写的html会把母板写的替换掉。

母模板中至少应该标明三个区域:

页面内容、CSS样式区、JS代码区

给子模板预留出加载CSS代码 加载JS代码的区域。

这样子版可以自己编辑CSS\JS代码,更加灵活。

子板加载自己的JS代码:



子板加载自己的CSS代码:



这样子页面不仅可以用主页的html,还可以有自己的样式和JS代码。

在模板的基础上扩展 super

super方法,可以在模板原有的基础上扩展(可以保留母板的html代码)(并且可以连续用多次):

组件的导入

写一个html组件(不是完整的html页面)

把这个组件导入页面。



使用include可以直接导入html代码(需要提前写好一个固定的html组件页面):

模型层之前期准备

sqlite3缺点

  1. 自带的sqlite3数据库对时间字段不敏感 有时候会展示错乱

    所以我们习惯切换成常见的数据库比如MySQL django orm并不会自动帮你创建库 所以需要提前准备好

时间字段补充

如下通过ORM添加了数据库的时间字段



有两种类型的时间字段:

auto_now: 每次操作数据都会自动更新当前时间(只要动表就更新时间)

auto_now_add: 创建数据自动获取当前时间并更新 后续修改不人为操作的情况下不会更新(只要不改时间字段,改其他字段不会触发更新)

添加双下str方法,易于查看对象:

django测试模型层

单独测试django某个功能层:



提示你定义好环境。

django默认情况下是要把项目跑起来测试,不支持单py文件测试。

如果想要测试某个py文件(主要models.py):

python console

测试环境1:pycharm提供的python console



特点:在终端测试无法保存

搭建测试环境

测试环境2:自己搭建(自带的test或者自己创建)

1.拷贝manage.py前四行
2.自己再加两行
import django
django.setup()

这里才可以单独导入模型层进行测试:



必须要把环境准备好,才能导入模型层:



不要随便改顺序,会报错。

查看orm底层SQL语句

django orm底层还是SQL语句 我们是可以查看的

如果我们手上是一个QuerySet对象 那么可以直接点query查看SQL语句



ps:SQL语句查询到数据之后 会把数据封装进对象

对于create方法不能拿到queryset对象:



如果想查看所有orm底层的SQL语句,可以在Django项目的settings.py文件中,在最后复制粘贴如下代码:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}

ORM常用关键字

1.create()

创建数据并直接获取当前创建的数据对象

res = models.User.objects.create(name='阿兵', age=28)
res = models.User.objects.create(name='oscar', age=18)
res = models.User.objects.create(name='jerry', age=38)
res = models.User.objects.create(name='jack', age=88)
print(res)

2.filter()

根据条件筛选数据

结果是QuerySet [数据对象1,数据对象2]

res = models.User.objects.filter()
res = models.User.objects.filter(name='jason')
res = models.User.objects.filter(name='jason', age=19) # 括号内支持多个条件但是默认是and关系



查询到一个对象的情况:



括号内支持多个条件,条件之间是and关系:

3.first() last()

QuerySet支持索引取值但是只支持正数 并且orm不建议你使用索引

res = models.User.objects.filter()[1]
res = models.User.objects.filter(pk=100)[0] # 数据不存在索引取值会报错
res = models.User.objects.filter(pk=100).first() # 数据不存在不会报错而是返回None
res = models.User.objects.filter().last() # 数据不存在不会报错而是返回None

queryset不支持负索引:



queryset推荐使用first\last、这跟直接使用索引0有什么区别?

原因是查询不到会报错!



使用first就不会报错,返回一个None。



last用于替代负数索引。补充说明queryset列表使支持切片的。

4.update()

更新数据(批量更新)
models.User.objects.filter().update() 批量更新
models.User.objects.filter(id=1).update() 单个更新

更新filter筛选出来的所有数据!筛出来一个就更新一个,筛出来一群就更新一群。

5.delete()

删除数据(批量删除)

models.User.objects.filter().delete()      批量删除
models.User.objects.filter(id=1).delete() 单个删除

这些方法都是queryset对象的方法。

6.all()

查询所有数据

结果是QuerySet [数据对象1,数据对象2]注意这里是列表

res = models.User.objects.all()

7.values()

根据指定字段获取数据(想匹配获取多个对象中的数据) 结果是QuerySet [{},{},{},{}]注意这里是列表套字典



上述这三种写法效果一样:



获取一个字段时的queryset对象:



ps:列表套字典,但还是queryset对象。

queryset对象支持for循环:

8.values_list()

根据指定字段获取数据 结果是QuerySet [(),(),(),()] 注意是列表套元祖

res = models.User.objects.all().values_list('name','age')



获取所有数据的name和age字段

9.distinct()

去重(对结果集进行去重、不会删除原数据)

数据一定要一模一样才可以 如果有主键肯定不行

res = models.User.objects.values('name','age').distinct()

数据库中含有两个相同的字段:(主键不相同)



无法去重:



这个去重是针对于拿到的字段对象用的(不包含主键)

10.order_by()

根据指定条件排序 默认是升序 字段前面加负号就是降序

res = models.User.objects.all().order_by('age')
print(res)

默认按照升序排序:



改降序:加减号



支持写多个排序条件

11.get()

根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用

res = models.User.objects.get(pk=1)
print(res)
res = models.User.objects.get(pk=100, name='jason')
print(res)

get直接获取到数据对象



条件一旦不存在,直接报错:



和之前一样,多个查询条件之间的关系是and。

12.exclude()

取反操作

res = models.User.objects.exclude(pk=1)
print(res)

exclude取反操作:

不要主键等于1的数据。



查看SQL:

13.reverse()

颠倒顺序(被操作的对象必须是已经排过序的才可以)

res = models.User.objects.all()
res = models.User.objects.all().order_by('age')
res1 = models.User.objects.all().order_by('age').reverse()
print(res, res1)

reverse颠倒顺序:



使用这个方法必须有个前提,被操作的对象必须已经排过序。否则不会颠倒顺序。

14.count()

统计结果集中数据的个数

res = models.User.objects.all().count()
print(res)

15.exists()

判断结果集中是否含有数据 如果有则返回True 没有则返回False

res = models.User.objects.all().exists()
print(res)
res1 = models.User.objects.filter(pk=100).exists()
print(res1)

练习 (使用模板继承)

母板:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title> {% block link_css %}
{% load static %}
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
{% endblock %} {% block link_js %}
<script src="{% static 'js/jquery3.6.1.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
{% endblock %} {% block style_css %}
<style>
body {
background: radial-gradient(200% 100% at bottom center, #f7f7b6, #e96f92, #1b2947);
background: radial-gradient(220% 105% at top center, #1b2947 10%, #75517d 40%, #e96f92 65%, #f7f7b6);
/*overflow: hidden;*/
height: 100%;
}
</style>
{% endblock %} </head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container-fluid">
<div class="row"> <div class="col-md-2">
{% block list-group %}
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
{% endblock %}
</div> <div class="col-md-10">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div class="panel-body"> {% block panel-body %} <div class="jumbotron">
<h1>USER INFO</h1> <p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
<a href="{% url 'user_view' 'add' %}" class="btn btn-success">ADD DATA</a>
<table class="table table-hover">
<thead>
<tr>
<th>NAME</th>
<th>AGE</th>
<th>COMPANY</th>
<th>INFO</th>
<th>OPREATION</th>
</tr>
</thead>
<tbody>
{% for user in user_data %}
<tr>
<th>{{ user.name }}</th>
<th>{{ user.age }}</th>
<th>{{ user.company }}</th>
<th>{{ user.info }}</th>
<th> <!-- 在前端使用反向解析 -->
<a href="{% url 'user_view' 'edit' %}?edit_id={{ user.pk }}"
class="btn btn-primary btn-xs">EDIT</a>
<a href="{% url 'user_view' 'delete' %}?edit_id={{ user.pk }}"
class="btn btn-danger btn-xs delBtu">DELETE</a>
</th>
</tr>
{% endfor %}
</tbody>
</table> {% endblock %} </div>
<div class="panel-footer"></div>
</div>
</div> </div>
</div> {% block local_js %}
<script> <!-- 我们绑定的事件 是优先于默认事件的 -->
$('.delBtu').click(function () {
let res = confirm('确定要删除吗?')
if (res) {
} else {
return false
}
})
</script>
{% endblock %} </body>
</html>

子板:

{% extends 'show_page.html' %}

{% block panel-body %}

    <h1 class="text-center">ADD USER</h1>
<form action="{% url 'user_view' 'add' %}" method="post">
<p>NAME:
<input type="text" name="name" class="form-control">
</p>
<p>AGE:
<input type="text" name="age" class="form-control">
</p>
<p>COMPANY:
<input type="text" name="company" class="form-control">
</p>
<p>INFO:
<textarea class="form-control" name="info"></textarea>
</p>
<p>
<input type="submit" class="btn-success btn btn-block">
</p> </form>
{% endblock %}

模板层之标签 自定义模板语法 模板的继承与导入 搭建测试环境 ORM常用关键字的更多相关文章

  1. 模板层之标签 自定义过滤器及标签 模板的继承与导入 模型层之前期准备 ORM常用关键字

    目录 模板层之标签 if判断 for循环 自定义过滤器.标签及inclusion_tag(了解) 前期三步骤 自定义过滤器(最大只能接收两个参数) 自定义标签(参数没有限制) 自定义inclusion ...

  2. 模板层之标签、自定义模板语法、母版(模版)的继承与导入、模型层前期准备知识点、ORM常用关键字

    今日内容概要 模板层之标签 if判断 {% if 条件1 %} #条件1成立 <p>Hello!</p> #执行 {% elif 条件2 %} #条件1不成立 条件2成立 &l ...

  3. 12月14日内容总结——模板层之标签、自定义模板语法、母版(模版)的继承与导入、模型层前期准备知识点、ORM常用关键字

    目录 一.模板层之标签 分支结构if for循环 with(定义变量名) 二.自定义过滤器.标签及inclusion_tag(了解) 三.母版(模板)的继承与导入(重要) 四.模型层之前期准备 模型层 ...

  4. 模板层语法、模板层之标签、模板的继承与导入、模型层之ORM常见关键字

    模板层语法.模板层之标签.模板的继承与导入.模型层之ORM常见关键字 一.模板层语法 1.模板语法的传值 urls代码: path('modal/', views.modal) views代码: de ...

  5. Django 你需要掌握的模型层(标签、过滤器、模板的继承与导入)

    Django 模型层(标签.过滤器.模板的继承与导入) 好文章来自超哥:https://www.cnblogs.com/guanchao/p/11006062.html   过滤器/自定义过滤器 模板 ...

  6. Django 模型层(标签、过滤器、模板的继承与导入)

    过滤器/自定义过滤器 模板语法中的过滤器类似于python中的内置方法,在我们把数据从后端通过rander传入到前端html文件中之后,在前端我们可以通过模板语法,对传入的数据再进行以通骚操作. 首先 ...

  7. Django 模版语法 测试环境 ORM单表查询

    模版语法 传值 视图函数向前端html页面传值,基本上所有的数据类型都可以渲染在前端页面上. views.py from django.shortcuts import render, redirec ...

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

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

  9. Django框架之第五篇(模板层) --变量、过滤器、标签、自定义标签、过滤器,模板的继承、模板的注入、静态文件

    模板层 模板层就是html页面,Django系统中的(template) 一.视图层给模板传值的两种方法 方式一:通过键值对的形式传参,指名道姓的传参 n = 'xxx'f = 'yyy'return ...

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

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

随机推荐

  1. Android 图表开源库调研及使用示例

    原文地址: Android图表开源库调研及使用示例 - Stars-One的杂货小窝 之前做的几个项目都是需要实现图表统计展示,于是做之前调研了下,做下记录 概述 AAChartCore-Kotlin ...

  2. MongoDB的聚合笔记

    1,聚合 聚合(aggregate)主要用于计算数据,类似sql中的sum().avg(). 常用的表达式如上图. 1.1,aggregate  语法 语法:     db.集合名称.aggregat ...

  3. 2023年奔走的总结---吉特日化MES 智能搬运AGV 篇三

    <2023年奔走的总结---吉特日化MES 项目趣事 篇一> <2023年奔走的总结---吉特日化MES 制药项目 篇二> <2023年奔走的总结---吉特日化MES 智 ...

  4. Selenium-[实例]猫眼电影爬取

    import random import time from selenium import webdriver from selenium.webdriver import ActionChains ...

  5. android webview(外部浏览器)调起app

    最近写的项目中涉及外部浏览器以及项目webview中调起app,所以总结下,和大家分享下. 总的实现方法还是比较简单的, 1:在清单中注册 首先在AndroidManifest文件中,注册一个过滤器 ...

  6. --{module_name}_binary_host_mirror和--{module_name}_binary_site

    --{module_name}_binary_host_mirror和--{module_name}_binary_site demo // .npmrc文件 sass_binary_site=htt ...

  7. SpringBoot整合JavaFx(十三)

    SpringBoot整合JavaFx(十三) 在Java中,基本上万物可springboot- 整合了spring全家桶,你可以很方便整合它的生态框架. JavaFx也能整合springboot,下面 ...

  8. 前端布局flex从入门到入土

    前端布局flex从入门到入土 作为一个后端,谈不上多会前端,但是一些常见的布局都可以做到,例如flex布局.推荐菜鸟教程的布局:https://www.runoob.com/w3cnote/flex- ...

  9. thymeleaf特殊字符输出转义

    thymeleaf特殊字符输出转义,字符串包括/@#¥%&*,正常来说他们输出会被转义掉.主要是使用了th:inline="javascript"标签,它会自动安全转义字符 ...

  10. Java 并发编程(四)同步工具类

    本文使用的 JDK 版本为 JDK 8 基本同步工具类 闭锁(CountDownLatch) 闭锁是一种工具类,可以延迟线程的进度直到其到达终止状态.闭锁的作用相当与一扇门:在闭锁的状态到达之前,这扇 ...