django模板之标签、继承、模型层之ORM常用关键字
模板层之标签
会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断
{% if d1 %}
内容块
{% endif %}
{% if 条件1(可以自己写也可以用传递过来的数据) %}
<p>今天是周三了</p>
{% elif 条件2(可以自己写也可以用传递过来的数据) %}
<p>百日冲刺</p>
{% else %}
<p>没多少时间了!</p>
{% endif %}
for:循环遍历每一个元素
语法:
{% for foo in d1 %}
<p>{{ foo }}</p>
{% endfor %}
特点:for循环的元素必须是可迭代对象;集合是无序的,每次循环的结果不同
forloop- 添加循环序号
在for循环标签内使用,产生forloop对象
{% for k in d1 %}
{{ forloop }}
{% endfor %}
{% for k in t1 %} #t1是个空元组,会执行empty标签的数据
{% if forloop.first %}
<p>这是第一次循环{{ k }}</p>
{% elif forloop.last %}
<p>这是最后一次循环{{ k }}</p>
{% else %}
<p>这是中间循环{{ k }}</p>
{% endif %}
{% empty %}
<p>你给我传的数据是空的无法循环取值(空字符串、空列表、空字典)</p>
{% endfor %}
forloop对象内的属性:
详情参考:https://www.cnblogs.com/DuoDuosg/p/16983355.html
django模板语法取值操作:只支持句点符
django模板支持键也支持索引取值
d1 = {'name':'jason','age':18,'hobby':['read','music',{'a1':'haha','a2':'heihei'}]}
{{ d1.hobby.2.a1 }} #前端页面取值到haha,通过句点符
冷门了解:
{% with d1.hobby.2.a1 as h %} 复杂数据获取之后需要反复使用可以起别名
<a href="">{{ h }}</a>
{% endwith %}
代码验证:
urls.py:
from app01 import views
path('index/',views.index_func),
views.py:
def index_func(request):
i = 666
l1 = [11,22,33,44,55]
d1 = {'name':'jason','age':18,'hobby':['read','music',{'a1':'haha','a2':'heihei'}]}
s = False
m = True
t1 = ()
return render(request,'indexPage.html',locals())
indexPage.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if s %}
<p>今天是周三了</p>
{% elif m %}
<p>百日冲刺</p>
{% else %}
<p>没多少时间了!</p>
{% endif %}
{% 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 %}
{{ d1.hobby.2.a1 }}
<p>
{% with d1.hobby.2.a1 as h %}
<a href="">{{ h }}</a>
{% endwith %}
</p>
</body>
</html>
自定义过滤器、标签及inclusion_tag(了解)
"""
如果想要自定义一些模板语法 需要先完成下列的三步走战略
1.在应用下创建一个名字必须叫templatetags的目录
2.在上述目录下创建任意名称的py文件
3.在上述py文件内先编写两行固定的代码
from django import template
register = template.Library()
ps:报错需要重启django项目
"""
# 自定义过滤器(最大只能接收两个参数)
@register.filter(name='myadd')
def func1(a, b):
return a + b
{% load mytags %}
<p>{{ i|myadd:1 }}</p>
# 自定义标签(参数没有限制)
@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(局部的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()
{% load mytags %}
{% mymenu 20 %}
代码验证:
mytags.py:
from django import template
register = template.Library()
# 自定义过滤器(最大只能接收两个参数)
@register.filter(name='myadd')
def func1(a,b):
return a + b
views.py:
def index_func(request):
i = 666
l1 = [11,22,33,44,55]
d1 = {'name':'jason','age':18,'hobby':['read','music',{'a1':'haha','a2':'heihei'}]}
s = False
m = True
t1 = ()
return render(request,'indexPage.html',locals())
indexPage.html:
<p>{{ i|myadd:1 }}</p>
mytags.py:
# 自定义标签(参数没有限制)
@register.simple_tag(name='mytag')
def func2(a,b,c,d,e):
return f'{a}-{b}-{c}-{d}-{e}'
indexPage.html:
{% mytag 'jason' 'kevin' 'oscar' 'jery' 'tony' %}
mytags.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:
<ul>
{% for liStr in html %}
{{ liStr|safe }}
{% endfor %}
</ul>
indexPage.html:
{% mymenu 10 %}
模板的继承与导入(重要)
多个页面有很多相似的地方 我们可以采取下列方式
方式1:传统的复制粘贴
方式2:模板的继承
1.在模板中使用block划定子板以后可以修改的区域
{% block 区域名称 %}
{% endblock %}
2.子板继承模板
{% extends 'home.html' %}
{% block 区域名称 %}
子板自己的内容
{% endblock %}
ps:模板中至少应该有三个区域
页面内容区、css样式区、js代码区
补充:子板也可以继续使用模板的内容{{ block.super}}
代码验证:
urls.py:
# 模板的继承
path('home/',views.home_func),
path('login/',views.login_func),
path('register/',views.register_func),
views.py:
def home_func(request):
return render(request,'home.html')
def login_func(request):
return render(request,'loginPage.html')
def register_func(request):
return render(request,'registerPage.html')
home.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
{% block css %}
{% endblock %}
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.css' %}">
</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">
<div class="list-group">
<a href="/home/" class="list-group-item active">
首页资源
</a>
<a href="/login/" class="list-group-item">登录资源</a>
<a href="/register/" class="list-group-item">注册资源</a>
<a href="#" class="list-group-item">更多资源</a>
<a href="#" class="list-group-item">其它资源</a>
</div>
<div class="list-group">
<a href="#" class="list-group-item active">
首页资源
</a>
<a href="#" class="list-group-item">登录资源</a>
<a href="#" class="list-group-item">注册资源</a>
<a href="#" class="list-group-item">更多资源</a>
<a href="#" class="list-group-item">其它资源</a>
</div>
<div class="list-group">
<a href="#" class="list-group-item active">
首页资源
</a>
<a href="#" class="list-group-item">登录资源</a>
<a href="#" class="list-group-item">注册资源</a>
<a href="#" class="list-group-item">更多资源</a>
<a href="#" class="list-group-item">其它资源</a>
</div>
</div>
<div class="col-md-10">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
{% block content %}
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}
</div>
</div>
</div>
</div>
</div>
{% block js %}
{% endblock %}
</body>
</html>
loginPage.html:
{% extends 'home.html' %}
{% block css %}
<style>
#d1 {
color:red;
}
</style>
{% endblock %}
{% block content %}
<h1 class="text-center" id="d1">登录页面</h1>
<form action="">
<p>username
<input type="text" class="form-control">
</p>
<p>password:
<input type="text" class="form-control">
</p>
<input type="submit" class="btn btn-success">
</form>
{% endblock %}
{% block js %}
<script>alert('登录页面')</script>
{% endblock %}
registerPage.html:
{% extends 'home.html' %}
{% block css %}
<style>
#d2 {
color: greenyellow;
}
</style>
{% endblock %}
{% block content %}
<h1 class="text-center" id="d2">注册页面</h1>
<form action="">
<p>username
<input type="text" class="form-control">
</p>
<p>password:
<input type="text" class="form-control">
</p>
<input type="submit" class="btn btn-warning">
</form>
{% endblock %}
{% block js %}
<script>alert('注册页面')</script>
{% endblock %}
模板的导入(了解)
将某个html的部分提前写好 之后很多html页面都想使用就可以导入
{% include 'myform.html'%}
myform.html:
<h1 style="color: yellow">这是一个非常好看的form表单</h1>
registerPage.html:
{% include 'myform.html' %}
模型层之前期准备
1.自带的sqlite3数据库对时间字段不敏感,有时候会展示错乱,所以我们习惯切换成常见的数据库比如Mysql,django orm并不会自动帮你建库,所以需要提前准备好。
ps:如果使用的是旧数据库,可能新建表迁移会没有反应,因为一个项目绑定一个数据库,建议使用全新django项目和全新数据库
2.单独测试django某个功能层
默认不允许单独测试某个py文件,如果想要测试某个py文件(主要models.py)
测试环境1:pycharm提供的python console
测试环境2:自己搭建(自带的test或者自己创建)
1.拷贝manage.py前四行
2.自己再加两行
import django
django.setup()
3.django orm底层还是SQL语句 我们是可以查看的
如果我们手上是一个QuerySet对象 那么可以直接点query查看SQL语句
如果想查看所有orm底层的SQL语句也可以在配置文件添加日志记录
代码:
settings.py:
#数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'day05',
'USER':'root',
'PASSWORD':'Abcd1234',
'HOST':'127.0.0.1',
'PORT':3306,
'CHARSET':'utf8'
}
}
#ORM配置sql日志打印
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
test.py(orm sql增删改查临时环境搭建)
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday05.settings')
import django
django.setup()
from app01 import models
main()
ORM常用关键字(重要)
1.create() 创建数据并直接获取当前创建的数据对象
2.filter() 根据条件筛选数据,结果是QuerySet[数据对象1,数据对象2]
3.first() last() QuerySet支持索引取值但是只支持正数,并且orm不建议使用索引
4.update() 更新数据(批量更新)
5.delete() 删除数据(批量删除)
6.all() 查询所有数据 结果是QuerySet[数据对象1,数据对象2]
7.values() 根据指定字段获取数据 结果是QuerySet [{},{},{}]
8.values_list() 根据指定字段获取数据 结果是QuerySet [(),(),()]
9.distinct() 去重 数据一定要一模一样才可以,如果有主键肯定不行(因为主键是非空且唯一)
10.order_by() 根据指定条件排序 默认是升序 字段前面加负号就是降序
11.get() 根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用
12.exclude() 取反操作
13. reverse() 颠倒顺序(被操作的对象必须是经过排序的才可以)
14.count() 统计结果集中数据的个数
15.exists() 判断结果集中是否含有数据 如果有则返回True,没有返回False
代码:
from django.test import TestCase
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoday05.settings')
import django
django.setup()
from app01 import models
models.User.objects.filter()
# 1.create() 创建数据并直接获取当前创建的数据对象
res = models.User.objects.create(name='jason',age=28)#用户对象jason
res = models.User.objects.create(name='oscar',age=18)#用户对象oscar
res = models.User.objects.create(name='jerry',age=38)#用户对象jerry
res = models.User.objects.create(name='jack',age=88)#用户对象jack
res = models.User.objects.create(name='tony',age=33)#用户对象tony
# 2.filter() 根据条件筛选数据,结果是QuerySet[数据对象1,数据对象2]
res = models.User.objects.filter() #queryset[对象1,对象2]
res = models.User.objects.filter(name='jason') #queryset[对象]
res = models.User.objects.filter(name='jason',age=19) #括号内支持多个条件但是默认是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,有值返回用户对象
# 4.update() 更新数据(批量更新)
models.User.objects.filter().update() 批量更新
models.User.objects.filter(id=1).update(name='winter',age=22) 单个更新
# 5.delete() 删除数据(批量删除)
models.User.objects.filter().delete() 批量删除
models.User.objects.filter(id=1).delete() 单个删除
# 6. all() 查询所有数据 结果是QuerySet[数据对象1,数据对象2]
res = models.User.objects.all()
# 7.values() 根据指定字段获取数据 结果是QuerySet [{},{},{}]
res = models.User.objects.all().values('name')
res = models.User.objects.filter().values()
res = models.User.objects.values()
# 8.values_list() 根据指定字段获取数据 结果是QuerySet [(),(),()]
res = models.User.objects.all().values_list('name','age')
# 9.distinct() 去重 数据一定要一模一样才可以,如果有主键肯定不行(因为主键是非空且唯一)
res = models.User.objects.values('name','age').distinct()
# 10.order_by() 根据指定条件排序 默认是升序 字段前面加负号就是降序
res = models.User.objects.all().order_by('-age')
# 11.get() 根据条件筛选数据并直接获取到数据对象 一旦条件不存在会直接报错 不建议使用
res = models.User.objects.get(pk=1) #用户对象
res = models.User.objects.get(pk=100)
# 12.exclude() 取反操作
res = models.User.objects.exclude(pk=1)
# 13. reverse() 颠倒顺序(被操作的对象必须是经过排序的才可以)
res=models.User.objects.all().order_by('age')
res1=models.User.objects.all().order_by('age').reverse()
# 14.count() 统计结果集中数据的个数
res = models.User.objects.all().count()
# 15.exists() 判断结果集中是否含有数据 如果有则返回True,没有返回False
res = models.User.objects.all().exists() #True
res1 = models.User.objects.filter(pk=100).exists() #False
print(res,res1)
main()
分类:
Django
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗