Django模板语法
Posted 游客520
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django模板语法相关的知识,希望对你有一定的参考价值。
文章目录
前言
通过本节可以学到:
- 向模板中传递数据
- 不同python数据类型填充模板
- 模板中使用判断语句
- 模板中使用循环语句
新建一条路由
我们先添加一条路由:
# url.py
from django.urls import path
from app01 import views
urlpatterns = [
path("tpl", views.tpl),
]
from django.shortcuts import render, HttpResponse
def tpl(request):
return render(request, 'tpl.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
</body>
</html>
看到下面的页面,说明我们的路由创建好了。
python不同数据类型填充模板
视图向模板中传递数据
上节我们讲到了render函数,讲到了render函数的前两个参数request和template_name,它还由第三参数context,默认为None。我们可以通过context将数据传递给模板。以字符串、列表、字典、嵌套数据类型进行讲解。
视图函数渲染模板流程:
字符串填充模板
def tpl(request):
name = '张三'
return render(request, 'tpl.html', 'n1': name)
为模板传递 ‘n1’: name,其中n1是在模板中将要调用的变量名。
那么,模板中怎么使用n1呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
<p> n1 </p>
</body>
</html>
在模板中只需要使用双大括号* 变量名 *即可调用视图函数中的name的值(张三)。
示例中n1是一个字符串,n1是一个整数或浮点数能不能传递?大家可以自行测试下。
列表填充模板
上面演示了视图向模板传递字符串,那么能不能传递列表呢?
Of course!当然可以了!
def tpl(request):
roles = ['管理员', 'CEO', 'CFO']
return render(request, 'tpl.html', 'roles': roles)
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<h1>模板语法学习</h1>
<p> roles </p>
</body>
</html>
列表以字符串的形式展示在了页面上。这显然不符合我们的需求。那如何来获取其中的某个元素呢?
就向列表取值一样,可以使用索引。不同的是模板中是使用 list.index 获取值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
<p> roles.1 </p>
</body>
</html>
这样就能把列表中索引为1的值显示在页面上。
同样的,大家可以试试索引为0、索引为2,前端展示的内容。
字典填充模板
def tpl(request):
user_info = "name": '李四', 'salary': 10000, 'role': "CTO"
return render(request, 'tpl.html', 'user_info': user_info)
模板中如果使用字典,通过key获取value值,格式: dict.key
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
<p><span>姓名:</span> user_info.name </p>
<p><span>角色:</span> user_info.role </p>
<p><span>薪资:</span> user_info.salary </p>
</body>
</html>
嵌套数据类型填充模板
如果遇到像 [‘name’: ‘张三’, ‘age’: 19, ‘name’: ‘李四’, ‘age’: 30,‘name’: ‘王五’, ‘age’: 27]这种嵌套的数据怎么处理呢?其实方法和python中获取是一样的,不同的是模板语法中使用的是点,python中用的是中括号。
def tpl(request):
data_list = [
'name': '张三', 'age': 19,
'name': '李四', 'age': 30,
'name': '王五', 'age': 27,
]
return render(request, 'tpl.html', 'data_list': data_list)
html中获取李四年龄为例。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
<p> data_list.1.age </p>
</body>
</html>
data_list.1获取李四所在的字典,data_list.1.age李四所在字典的年龄key。
模板中的判断语句
模板中同样可以使用判断语句,其格式如下
% if 条件 %
语句
% elif 条件 %
语句
% else %
语句
% endif %
elif和else语句可以无。
示例:
def tpl(request):
name = '张三'
return render(request, 'tpl.html', 'n1': name)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
% if n1 == '张三' %
<p>这个人是张三</p>
% else %
<p>这个人不是张三</p>
% endif %
</body>
</html>
模板中的循环语句
模板中同样可以可以使用循环语句,其格式如下:
% for item in iter %
循环体
% endfor %
示例,对字典进行循环:
def tpl(request):
user_info = "name": '李四', 'salary': 10000, 'role': "CTO"
return render(request, 'tpl.html', 'user_info': user_info)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板语法</title>
</head>
<body>
<h1>模板语法学习</h1>
% for item in user_info.items %
<div> item</div>
% endfor %
</body>
</html>
示例中循环了字典的items,同样也可以循环keys和values,注意不用加括号
最后总结以下:
所谓模板语法,其本质上是在html中写一些占位符,由数据对这些占位符进行替换和处理。
综合案例
通过requests将腾讯抓取腾讯新闻标题、链接等信息,并展示在我们的新闻中心页面上。
# urls.py
from django.urls import path
from app01 import views
urlpatterns = [
path("news", views.news),
]
# views.py
from django.shortcuts import render, HttpResponse
def news(req):
import requests
headers =
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
params =
'pull_urls': 'news_top_2018',
response = requests.get(
'https://i.news.qq.com/trpc.qqnews_web.pc_base_srv.base_http_proxy/NinjaPageContentSync',
params=params,
headers=headers,
)
return render(req, 'news.html', 'data': response.json())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>新闻中心</title>
</head>
<body>
<h1>新闻中心</h1>
<ul>
% for item in data.data %
<li><a href=" item.url "> item.title </a></li>
% endfor %
</ul>
</body>
</html>
最终效果:
如果对您有所帮助的话感谢您点赞收藏。欢迎评论区留言讨论。
django 源码模板的语法符号的使用
目录
django 基础
render 原理
代码:
def ab_render(request):
temp = Template("<h1>{{user_dict}}{{user_dict.username}}{{user_dict.password}}</h1>")
user_dict = Context({'user_dict':{'username':'jason','password':123}})
res = temp.render(user_dict)
return HttpResponse(res)
视图函数并一定就是函数 也可以是类
FBV:基于函数的视图
CBV:基于类的视图
CBV基本写法
from django.views import View
class MyLogin(View):
def get(self,request):
return render(request,'login.html')
def post(self,request):
return HttpResponse('我是类里面的post方法')
urls 文件里的urls
url(r'^login/',views.MyLogin.as_view())
作用:
朝着login提交get请求会自动执行Mylogin里面的fet方法
而提交post请求也会自动执行Mylogin里面的post方法
研究源码的突破口
url(r'^login/',views.MyLogin.as_view())
怎么看源码:
猜想
as_view要么是类里面定义的普通函数 @staticmethod
要么是类里面定义的绑定给类的方法 @classmethod
看源码发现是绑定给类的方法
看源码不需要每一句都看懂 只看自己能够看得懂
步骤如图:
第一步
第二步 从上至下一次查看
第三步:
django settings源码
django暴露给用户一个可以自定义的配置
但是内部也有默认的配置
用户配置了就用用户的 用户没有配就用默认的
模板的语法符号
{{}} 变量相关
{% %} 逻辑相关
模板层之模板传值
python基本数据类型全部支持传递给html文件
函数
类
函数和对象会自动加括号
# 模板语法不支持传参
对象
后端给html文件传递数据的两种方式
1.指名道姓
return render(request,'index.html',{'n':n,'f':f})
2.locals() # 会将当前名称空间中所有的变量名全部传递给html页面
return render(request,'index.html',locals())
html页面上 如何获取到后端传递过来的数据
{{ 变量名 }}
取值
django模板语法取值 只有一种操作方式 句点符 .
点索引
点键
<p>{{ l.2 }}</p>
<p>{{ d.username }}</p>
<p>{{ d.password }}</p>
<p>{{ d.hobby.1.username.1 }}</p>
模板语法之过滤器 |
关键字的方法:
|length :获取数据的长度
|add :加法的运算
|default :默认值(判断值是否为空)
|truncatechars :截取字符(截取5个字符 三个点也算)
|truncatewords :截取单词(截取8个单词 三个点不算)
|filesizeformat :文件的大小
|slice : 切片的操作
|date : 日期格式化
|safe : 转义
使用方式
<p>过滤器 |左边的会当做过滤器的第一个参数 过滤器名右边的会当做过滤器的第二个参数</p>
<p>求数据长度:{{ s|length }}</p>
<p>加法运算:{{ n|add:10 }}、{{ s|add:13132 }}、{{ s|add:'DSB' }}</p>
<p>默认值(判断值是否为空):{{ b|default:'这个b布尔值是True' }}、{{ ff|default:'这个ff布尔值是Flase' }}</p>
<p>截取字符(截取5个字符 三个点也算):{{ s|truncatechars:8 }}</p>
<p>截取单词(截取8个单词 三个点不算):{{ ss|truncatewords:8 }}、{{ sss|truncatewords:4 }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>切片操作:{{ s|slice:'0:2' }}、{{ s|slice:"0:8:2" }}</p>
<p>日期格式化:{{ ddd|date:'Y年/m月/d日' }}</p>
<p>转义:{{ res|safe }}、{{ res1 }}、后端直接标识安全:{{ res2 }}</p>
效果:
文件大小
效果:
前后端取消转义
前端
|safe
后端
from django.utils.safestring import mark_safe
res2 = mark_safe('<h1>你好啊</h1>')
可在后端直接使用mark_safe方法 使前端不用加 |safe 都可以直接运行res2
总结:
前端代码不一定非要在前端页面写,可以在后端写好传递给前端页面使用 这样的话 你就可以利用到后端更加多的逻辑语法
模板语法之标签 (逻辑相关)
{% for foo in l %} <!--l = [1,2,3,4,5,6]-->
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次了啊~</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>for循环的对象内部没有值</p>
{% endfor %}
添加描述信息后
效果:
没有相对参数时
效果:
for 循环
效果:
当一个值获取的步骤非常繁琐 但是又需要在很多地方用到 我们可以用起别名的方式来简化代码
效果:
自定义过滤器 标签 inclusion_tag
先完成以下前期准备工作:
1.在应用名下新建一个名字必须叫templatetags文件夹
2.在该文件夹内新建一个任意名称的py文件(eg:mytag)
3.在该文件内 必须先写以下两句代码
from django.template import Library
register = Library()
# 自定义过滤器
@register.filter(name='my_sum')
def index(a,b):
return a + b
# 自定义标签
@register.simple_tag(name='my_baby')
def xxx(a,b,c,d):
return '%s?%s?%s?%s'%(a,b,c,d)
# 自定义inclusion_tag
@register.inclusion_tag('demo.html',name='myin')
def index1(n):
l = []
for i in range(n):
l.append(i)
# 将列表传递给demo.html
# return locals()
return {'l':l}
使用方法:
<p>自定义过滤器的使用</p>
{% load mytag %}
<p>{{ 10|my_sum:90 }}</p>
<p>自定义标签的使用</p>
{% load mytag %}
<p>{% my_baby 1 2 3 'hello world' %}</p>
<p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p>
{% if 10|my_sum:100 %}
<p>条件成立</p>
{% endif %}
{% if my_baby 1 2 3 4 %}
<p>条件成立</p>
{% endif %}
<p>自定义inclusion_tag的使用</p>
{% load mytag %}
{% myin 5 %}
# 总结 页面上使用他们 统一先导入
{% load mytag %}
代码:
<p>自定义过滤器的使用</p>
{% load mytag %}
<p>{{ 10|my_sum:90 }}</p>
效果:
代码:
效果:
自定义的过滤器可以在逻辑语句中而自定义的标签不可以
<p>自定义的过滤器可以在逻辑语句中而自定义的标签不可以</p>
{% if 10|my_sum:100 %}
<p>条件成立</p>
{% endif %}
{% if my_baby 1 2 3 4 %}
<p>条件成立</p>
{% endif %}
代码:
# 自定义inclusion_tag
@register.inclusion_tag('demo.html',name='myin')
def index1(n):
l = []
for i in range(n):
l.append(i)
# 将列表传递给demo.html
# return locals()
return {'l':l}
效果:
模板的继承
需求:某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面
当别人继承这个页面之后 如何修改对应的区域
某一个页面大部分区域都是公用的 那这个页面就可以作为模板页面
当别人继承这个页面之后 如何修改对应的区域
先在模板页面上通过block实现划定区域
{% block content %}
模板页面内容
{% endblock %}
子页面中先导入整个模板
{% extends '模板页面.html'%}
修改特定的区域 通过实现划定好的区域名称
{% block content %}
子页面内容
{% endblock %}
通常情况下 模板页面页面应该起码有三块区域
{% block css %}
模板页面内容
{% endblock %}
{% block content %}
模板页面内容
{% endblock %}
{% block js %}
模板页面内容
{% endblock %}
# 模板的block块越多 可扩展性越高
还支持子页面调用父页面对应区域的内容 并且可以无限次调用
{{ block.super }}
先在模板页面上通过block实现划定区域
先去视图层建立 views.py
def mdzz(request):
return render(request,'mdzz.html')
在去文件里写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% block css %}
{% 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-3">
<div class="list-group">
<a href="/mdzz/" class="list-group-item active">
首页
</a>
<a href="/register/" class="list-group-item">注册</a>
<a href="/loginn/" class="list-group-item">登录</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div>
<div class="col-md-9">
<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="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>
子页面中先导入整个模板
登录页面
def loginn(request):
return render(request,'loginn.html')
html文件代码:
{% extends 'mdzz.html' %}
{% block css %}
<style>
h2 {
color: red;
}
</style>
{% endblock %}
{% block content %}
{% include 'left.html' %}
<h2 class="text-center">登录页面</h2>
<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-primary">
</form>
{{ block.super }}
{% endblock %}
{% block js %}
{# <script>#}
{# alert(123)#}
{# </script>#}
{% endblock %}
通常情况下 模板页面页面应该起码有三块区域
注册页面
def register(request):
return render(request,'reg.html')
html文件代码:
{% extends 'mdzz.html' %}
{% block css %}
<style>
h2 {
color: green;
}
</style>
{% endblock %}
{% block content %}
<h2 class="text-center">注册页面</h2>
<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-danger">
</form>
{{ block.super }}
{{ block.super }}
{{ block.super }}
{{ block.super }}
{{ block.super }}
{{ block.super }}
{{ block.super }}
{% endblock %}
{% block js %}
{# <script>#}
{# alert(666)#}
{# </script>#}
{% endblock %}
基于django settings源码实现项目配置文件的 插拔式设计
以上是关于Django模板语法的主要内容,如果未能解决你的问题,请参考以下文章
每当我将 Python 代码放入 Django 模板时都会出现语法错误
带有 Python 2.7.6 和 Virtualenv 12.0.7 (OSX10,10.2) 的 Django 1.7.6 - 模板呈现模板语法错误