others linux服务器运维 django3 监控 k8s golang 数据库 大数据 前端 devops 理论基础 java oracle 运维日志

django templates 模板

访问量:1358 创建时间:2020-01-15

在访问网站,例如博客时,整个html页面的骨架是固定样式的,而内容文章会发生变化,整个html的骨架文件,我们称为模板文件,向模板中加入内容称为模板渲染。

django 返回数据的常用函数

在讲解模板渲染前,先看一下django用于返回http请求结果给浏览器的常见处理函数:

from django.shortcuts import render, redirect

from django.http import HttpResponse

def index(request):
    return HttpResponse("hello world!")
def index(request):
    return redirect("/helloworld")
from django.shortcuts import render
def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

通过HttpResponse实现render的功能,可以达到与render相同的功能,案例如下:

from django.http import HttpResponse
from django.template import loader

def my_view(request):
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request), content_type='application/xhtml+xml')

通过python的locals()代替render中的字典参数,locals()会将当前视图函数的所有对象加载到模板当中,会浪费系统内存资源:

def my_view(request):
    return render(request,'page.html',locals())

通过上面的案例,我们可以看到django不同的返回函数的功能,通常我们用render()函数来进行渲染模板并返回给浏览器。

django template 模板使用案例

创建新的项目mysite与应用myapp

django-admin startproject mysite
cd mysite
python3 manage.py startapp myapp

安装应用,mysite/settings.py

[root@work1 mysite]# vim mysite/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',    #<--增加一行
]

创建templates目录用于存储模板文件,并配置mysite项目找到模板目录:

[root@work1 mysite]# mkdir templates
[root@work1 mysite]# vim mysite/settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  #< -- 要修改的内容,这样django能找到模板文件
        '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',
            ],
        },
    },
]

配置urls.py

[root@work1 mysite]# vim mysite/urls.py 

from django.contrib import admin
from django.urls import path, include  #<--增加include
urlpatterns = [
    path('myapp/',include('myapp.urls')), #<--通过include,包含myapp的urls.py
    path('admin/', admin.site.urls),
]
[root@work1 mysite]# vim myapp/urls.py  #编辑新文件
from django.urls import path
from . import views
urlpatterns = [
    path('', views.index, name='index'),
]

添加myapp.views.index视图

[root@work1 mysite]# vim myapp/views.py 
from django.shortcuts import render

def index(request):
    var1= 'hello world'
    list1=['第一','第二','第三']
    dict1={'username':'zhangsan', 'password':'121'}
    return render(request,'myapp.html',locals())

编辑模板文件,在模板中渲染var1变量,通过{{ var_name }}来引用具体变量或者具体类实例的某个属性。

[root@work1 mysite]# vim templates/myapp.html
<!DOCTYPE html>
<html>
<head>
<title>django</title>
</head>
<body>
<h3>var1: {{ var1 }}</h3>
<p>list1: {{ list1 }}</p>
<p>dict1: {{ dict1 }}</p>
<p>{{ dict1.username }}</p>
</body>
</html>
# 运行django服务,访问http://你的IP:PORT/myapp查看页面效果。

django template 模板高级内容

django 模板for循环

在django模板中,可以通过for循环,遍历字典、列表、或者数据查询all()/filter()返回的集合。修改myapp.html,实现在模板中使用for循环遍历。

[root@localhost mysite]# vim templates/myapp.html 
<!DOCTYPE html>
<html>
<head>
<title>django</title>
</head>
<body>

{% for l in list1 %}
<p>{{ forloop.counter }} : {{ l }}</p>
{% endfor %}

{% for k,v in dict1.items %}
<h3>{{ k }}: {{ v }}</h3>
{% endfor %}
</body>
</html>
# 运行django服务,访问http://你的IP:PORT/myapp查看页面效果。forloop

forloop是可以在django模板中引用的for循环计数变量.(通常用于特殊处理,例如页面元素增加特殊属性)

属性 含义
.counter 表示当前迭代次数,从1开始计数
.counter0 表示当前迭代次数,从0开始计数
.first 布尔值,是否是第一循环
.last 布尔值,判断是否是最后一次循环
.parentloop for循环嵌套使用时,获取上层循环

django 模板if判断

在django模板中使用if判断,注意==两边空格。修改并编辑templates/myapp.html如下

<!DOCTYPE html>
<html>
<head>
<title>django</title>
</head>
<body>
{% for l in list1 %}
  {% if l == "第一" %}
    <p> 这是第一</p>
  {% elif l == "第二" %}
    <p> 这是第二</p>
  {% else %}
    <p> 这是第三</p>
  {% endif %}
{% endfor %}
</body>
</html>

还可以使用!=, >=, <=, >, < ;可以使用and, or 连接多个判断条件not, in, not in;还可以使用and, or, not, in, not in ;还可以使用{% ifequal var1 var2 %} {% ifnotequal var1 var2 %} 等

django 模板包含include

编辑templates/base.html

<!DOCTYPE html>
<html>
<head>
<style>
.header {
    background-color:black;
    color:white;
    text-align:center;
    padding:5px;
}
#nav {
    line-height:30px;
    background-color:#eeeeee;
    height:300px;
    width:100px;
    float:left;
    padding:5px;          
}
#content {
    width:350px;
    float:left;
    padding:10px;        
}
#footer {
    background-color:black;
    color:white;
    clear:both;
    text-align:center;
   padding:5px;
}
</style>
</head>
<body>
{% include 'header.html' %}
{% include 'nav.html' %}

<div id="content">
 <h2>标题</h2>
 <p>主要内容</p>
</div>

{% include 'footer.html' %}
</body>
</html>

编辑include子页面header.html ,header.html ,header.html

[root@localhost mysite]# vim templates/header.html 
<div class="header">
<h1>{{ var1 }}</h1>
</div>

[root@localhost mysite]# vim templates/header.html 
<div id="nav">
<ul>
  <li>垂直导航</li>
</ul>
</div>

[root@localhost mysite]# vim templates/header.html 
<div id="footer">
底部
</div>

[root@localhost mysite]# vim myapp/views.py 
from django.shortcuts import render
def index(request):
    var1= 'hello world'
    list1=['第一','第二','第三']
    dict1={'username':'zhangsan', 'password':'121'}
    return render(request,'base.html',locals())    #< 修改返回base.html

运行django服务,并访问http://你的IP:PORT/myapp

通过include with传递变量,修改base.html文件增加一行{% include 'header.html' with var1='1111' %},查看效果。

{% include 'header.html' %}
{% include 'header.html' with var1='1111' %}  

django 模板继承

修改templates/base.html

<!--#删除下面的内容-->
<!--
<div id="content">
 <h2>标题</h2>
 <p>主要内容</p>
</div>
-->
<!--#增加下面的内容-->
{% block content %}
{% endblock %}

新建并编辑templates/content.html

{% extends 'base.html' %}


{% block content %}
<div id="content">
 <h2>标题</h2>
 <p>主要内容</p>
</div>
{% endblock %}

修改视图,返回content.html

[root@localhost mysite]# vim myapp/views.py 
from django.shortcuts import render

def index(request):
    var1= 'hello world'
    list1=['第一','第二','第三']
    dict1={'username':'zhangsan', 'password':'121'}
    return render(request,'content.html',locals())   #要修改的地方

运行django服务,并访问http://你的IP:PORT/myapp

django模板过滤器

过滤器的作用是对模板变量进行格式化的输出,案例如下:

#修改index视图
[root@localhost mysite]# vim myapp/views.py 
from django.shortcuts import render
import datetime   
def index(request):
    var1= 'hello world'
    list1=['第一','第二','第三']
    dict1={'username':'zhangsan', 'password':'121'}
    addvar=1
    filesizeformatvar=123456789
    slicevar='hello world'
    datevar=datetime.datetime.now()
    lowervar="ABC"
    safevar="<a href='#'>这是一个safe过滤器测试</a>"
    return render(request,'content.html',locals())

#修改content.html文件
{% extends 'base.html' %}


{% block content %}
<div id="content">
 <h2>标题1</h2>
 <p>主要内容1</p>
 <p>{{ aa|default:"过滤器默认值"}}</p>
 <p>{{ filesizeformatvar|filesizeformat}}</p>
 <p>{{ addvar|add:"100"}}</p>
 <p>{{ slicevar|slice:":2"}}</p>
 <p>{{ datevar|date:"Y-m-d"}}</p>
 <p>{{ lowervar|lower}}</p>
 <p>{{ safevar|safe}}</p>
</div>
{% endblock %}

运行django服务,并访问http://你的IP:PORT/myapp

常用过滤器及含义:

过滤器名称 作用
add 字符串相加,数字相加,列表相加,如果失败,将会返回一个空字符串。
default 提供一个默认值,在这个值被django认为是False的时候使用。比如
first 返回列表中的第一个值。
last 返回列表中的最后一个值。
date 格式化日期和时间。
time 格式化时间。
join 跟python中的join一样的用法。
length 返回字符串或者是数组的长度。
length_is 字符串或者是数组的长度是否是指定的值。
lower 把所有字符串都编程小写。
truncatechars 根据后面给的参数,截断字符,如果超过了用…表示。
truncatewords 同truncatechars,这个是以一个单词为单位进行截断。
capfirst 首字母大写。
slice 切割列表。用法跟python中的切片操作是一样的,区间是前闭合后开放。
striptags 去掉所有的html标签。
safe 关闭变量的自动转义
floatformat 浮点数格式化。

过滤器可以自己定义。

自定义django模板全局变量

自定义模板全局变量可以在所有的模板中直接使用,案例如下:

#编辑settings.py增加"'myapp.context_processors.mytest',",如下
[root@localhost mysite]# vim mysite/settings.py
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', 
                'myapp.context_processors.mytest',  #< -- 新增
            ], 
        }, 
    }, 
] 

#编辑并增加全局变量处理函数
[root@localhost mysite]# vim myapp/context_processors.py
def mytest(request): 
    context = {'testvar1': 'testvar1', 'testvar2': 'testvar2'} 
    return context 

# 修改模板
[root@localhost mysite]# vim templates/content.html 
{% extends 'base.html' %} 
{% block content %} 
<div id="content"> 
 <h2>标题1</h2> 
 <p>主要内容1</p> 
 <p>{{testvar1}}</p> 
</div> 
{% endblock %} 

运行django服务,并访问http://你的IP:PORT/myapp,可以看待testvar1在视图中没有,但是模板中可以直接使用。这里你可以理解settings.py中TEMPLATES中的context_processors的作用。

总结:本章节介绍了django常用的视图返回函数、render模板渲染函数,模板标签if/for/with、模板包含与继承、模板过滤器、模板全局变量。实际上常用模板标签除了if/for还有:autoescape设置标签的自动转义, 关闭自动转义,spaceless去除html代码中的空白字符,url标签等,你可以自定义模板标签来实现你需要的功能;也可以自定义过滤器实现自己的功能,这里不再详细介绍自定义的内容。

登陆评论: 使用GITHUB登陆