Python Web----模板

一.配置模板引擎

Django项目通过模板引擎解释模板文件,一个Django项目中可以配置一个或多 个模板引擎。Django有内置的模板引擎,在创建项目时,配置文件settings.py的TEMPLATES变量中会添加默认设置。

模板引擎:就是数据渲染到字符串的工具/将变量数据渲染到按照模板语法书写的文本的工具

使用终端控制台创建项目chapter02

django-admin startproject chapter02

setting.py文件中templates项目默认项目:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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',
            ],
        },
    },
]
  • BACKEND:实现Django模板引擎API的模板引擎类的路径。
  • DIRS:设置模板源文件的目录列表,模板引擎将按列表中元素的顺序依次查找目录
  • APP_DIRS:声明是否在已安装的应用程序中查找模板。
  • OPTIONS:模板引擎的设置信息,dict 类型

Django的默认模板引擎为django.template.backends.django.DjangoTemplates,其语法为Django模板语言。Django 项目也支持目前广泛的模板引擎是Jinja2。
模板配置中的 APP DIRS默认值为True,表示模板引擎将在项目的所有应用目录中搜索模板文件。也可以在DIRS选项中指定搜索路径。Django 会按照DIRS选项中路径的先后顺序搜索模板文件。
 

 根目录下创建文件夹templates,html

templates文件下创建base.html在DIRS中进行添加路径

BASE_DIR指向当前目录路径

创建应用app

python manage.py startapp app

在应用app中创建文件夹templates,名字不能更改,必须是templates.

APP_DIR为True会去按照顺序dir 查找然后去应用的templates中查找

扫描二维码关注公众号,回复: 17327706 查看本文章
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'html')],
        #按照顺序进行查找
        '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',
            ],
        },
    },
]

二.使用模板类

调用模板类的构造函数Templare(),可以快速创建模板对象。调用模板render()方法,可以将模板渲染为HTML代码。

#首先进入环境
python manage.py shell

#调用模板类的构造函数
from django.template import Template
from django.template import Context 
t=Template("你的名字是:{
   
   {name}}")
context=Context({'name':"zhangsan"})
t.render(context)

三.使用模板文件

1.定义模板文件time.html文件

在应用目录下创建templates文件夹,在文件夹内创建time.py文件,下列模板显示视图传递时间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DEMO1</title>
</head>
<body>
    <h1>{
   
   {time}}</h1>
</body>
</html>
2.定义使用模板的视图函数

四种方法:

 1.get_template   2.render_to_string    3.TemplatesResponse   4.render

from datetime import datetime
from django.shortcuts import render
from django.http import HttpResponse

#get_template
from django.template.loader import get_template
time = datetime.today()#准备数据
def demo1(request):
    t=get_template('time.html')#载入模板文件
    html=t.render({'time':time})    #渲染模块
    return HttpResponse(html)     #将模块渲染结果返回客户端

#render_to_string
from django.template.loader import render_to_string
def demo2(request):
    str_response = render_to_string('time.html',{'time':time})
    return HttpResponse(str_response)

#TemplatesResponse
from django.template.response import TemplateResponse
def demo3(request):
    time=datetime.today()
    return TemplateResponse(request,'time.html',{'time':time})


#render
def demo4(request):
    time=datetime.today()
    return render(request,'time.html',{'time':time})
 3.配置URL

根路由:

from django.contrib import admin
from django.urls import path
from app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('demo1',views.demo1),
    path('demo2',views.demo2),
    path('demo3',views.demo3),
    path('demo4',views.demo4),
]

启动项目服务器

 四.变量

模板变量用于标识模板中会动态变化的数据,当模板被渲染时,模板引擎将其替换为视图中传递而来的真实数据。

                                                                { { variable }}

模板变量名由字母、数字和下画线(“_”)组成,但不能以下画线开头。 

模板语言通过点字符(“.”)进一步访问变量中的数据,但由于模板不明确模板变量的类型,因此模板引擎会按以下顺序进行尝试。

  1. 将变量视为字典,尝试根据键访问变量的值。
  2. 将变量视为对象,尝试访问变量的属性或方法
  3. 尝试访问变量的数字索引。

需要注意的是,若点字符后是一个方法,这个方法在调用时不带括号。

五.过滤器

 过滤器用于过滤变量,获取更精确的数据,其语法格式如下:

                                                   { { variables|filters }}

 使用多个管道符号(“|”)连接多个过滤器,连续对同一变量进行过滤,其语法格式如下:

                                            { { variables|filters1|filters2... }}

 需要注意的是,管道符号和变量、过滤器之间不能有空格

1.常 用 的 模 板 过 滤 器

2.常用过滤器

创建模板文件demo5.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        add1:{
   
   {a|add:"32"}},<br>
        add2:{
   
   { b|add:second}},<br>
        addslashes:{
   
   { c|addslashes }},<br>
            capfirst:{
   
   { d|capfirst }},<br>
            cut:{
   
   { f|cut:" "}},<br>
            date:{
   
   {g|date:"Y年m月d日"}},<br>
            default:{
   
   {h|default:"35"}},<br>
            dictsort:{
   
   { i|dictsort:"age"}},<br>
            escape:{
   
   {j|escape}},<br>
            
    </p>
</body>
</html>

定义使用模板的视图文件

def demo5(request):
    add1=[1,2,3]
    add2=[4,5,6]
    time=datetime.now()
    value=[ {'name':'张三','age':19},
            {'name':'李四','age':32},
            {'name':'王五','age':21},]
    c={'a':66,'b':add1,'second':add2,'c':"This is my compture.",'d':"laura",'f':"he ll o world",'g':time,'h':"",'i':value,'j':'<a&sd>',}
    return render(request,'demo5.html',c)

 根路由:

path('demo5',views.demo5)

启动项目服务器

2.1常用过滤器

 创建模板文件demo6.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        filesizeformat:{
   
   {k|filesizeformat}},<br>
        join:{
   
   { l|join:" // "}},<br>
        linenumbers"{
   
   { m|linenumbers}},<br>
        length:{
   
   { n|length }},<br>
        lower/upper:{
   
   { o|lower }},<br>
        random:{
   
   { p|random }},<br>
        truncatewords:{
   
   { q|truncatewords:2}},
    </p>
</body>
</html>

 定义使用模板的视图文件

def demo6(request):
    
    a={'k':123456789,'l':[1,2,3],'m':18,'n':"adsdffddd",'o':"ABJS",'p':[2,4,56,7],'q':"hello world,my name is myy"}
    return render(request,'demo6.html',a)

 配置根路由:

path('demo6',views.demo6)

 启动项目服务器

六.标签

  • 标签蕴含一定的逻辑,它的功能要比变量复杂,例如一些标签用于输出文本;一些标签通过执行循环或逻辑控制流;一些标签加载外部信息到模板中,以供后续变量的使用。
  • 标签格式简单,例如:{% tag %};也有一些标签必须成对出现,以标识模板文本的开始和结束,示例格式如下:

                                         {% tag %}    ... {% endtag %}

 1.常用的模块标签
2.for标签

创建模板文件demo7.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        <!-- 使用for标签遍历书单book_list,并输出所有书名 -->
        {% for r in data %}
         
        <!-- 模板中的for支持反向遍历列表 -->
        {% for r in data reversed%} //二选一
        <tr></tr>
        <li>{
   
   {r}}</li>
        {% endfor %}
    </p>
</body>
</html>

定义使用模板的视图文件

def demo7(request):
    data=['骆陀祥子','西游记','斗罗大陆']
    return render(request,'demo7.html',{'data':data}) 

配置URL(根路由):

path('demo7',views.demo7)

启动项目服务器

2.1 Django为for循环定义了一些变量
 2.2双层列表

若要遍历双层列表,可以解包内层列表中的每个元素到多个变量中

 创建模板文件demo8.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        {% for r in data %}
        第{
   
   {forloop.counter}}行:
            {%for a in r%}
            <li>{
   
   {a}}</li>
            {%endfor%}
        {%endfor%}
    </p>
</body>
</html>

 定义使用模板的视图文件

def demo8(request):
    data=[[1,2,3],[4,5,6],['a','b','c','d']]
    return render(request,'demo8.html',{'data':data}) 

 配置URL(根路由):

path('demo8',views.demo8),

遍历双层列表的操作在遍历字典时同样适用。示例代码如下:

创建模板文件demo9.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        {% for k,v in data.items %}
        <li>{
   
   {k}}={
   
   {v}}</li>
        {%endfor%}
    </p>
</body>
</html>

  定义使用模板的视图文件

def demo9(request):
    data = {'name':'zhangsan','age':30}
    return render(request,'demo9.html',{'data':data})

  配置URL(根路由):

path('demo9',views.demo9),

需要注意的是,操作符“.”查找优先于方法查找,因此若字典中包含键items,data.items将返回data[‘items’]而非data.items()。

3.for...empt 

for循环可以使用可选的{%empty%}子句,若给定的数组为空或无法找到,则显示{%empty%}子句的文本。

创建模板文件test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {% for r in data%}
    <tr></tr>
    <li>{
   
   {r}}</li>
    {% empty %}
        <li>抱歉,图书列表为空</li>
    {% endfor %}
</body>
</html>

  定义使用模板的视图文件

def test(request):
    data=[]
    return render(request,'test.html',{'data':data})

   配置URL(根路由):

 path('test',views.test),

 4.if/elif/else

if/elif/else是条件判断标签,与Python中的if、elif、else含义相同,若条件为True,显示相应子句中的内容。

创建模板文件test1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        分数:{
   
   {data}}
        班级:{
   
   {cls1}}
        {% if data >= 90%}
        等级:A
        {% elif data >= 80%}
        等级:B
        {% elif data >= 60%}
        等级:C
        {%else%}
        等级:D

        {%endif%}
    </p>
</body>
</html>

   定义使用模板的视图文件

def test1(request):
    data=80
    cls1="211"
    return render(request,'test1.html',{'data':data})

  配置URL(根路由):

path('test1',views.test1),

 

需要注意的是,模板语言的if标签不支持括号,若需明确表示混合语句中子句的优先级,应使用if嵌套语句。 

5.include

在使用include标签时需为其传入置于单/双引号中的变量或硬编码字符串,或指示模板的变量。

                                             {% include "foo/bar.html" %}

                                             {% include template_name %}

创建模板文件test2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        引入模块:{% include 'test1.html' %}<br>
        当前模块:当前日期{% now "Y年f月j日 H:i:s"%}
    </p>
</body>
</html>

j也代表日期,与d的区别在于其前面不加0。M与小写m的区别是其以英文缩写显示月份,而不是数字。另外F也代表月份,为英文月份全称。 

    定义使用模板的视图文件:

def test2(request):
    data=90
    cls1='985'
    return render(request,'test2.html',{'data':data,'cls1':cls1})

   配置URL(根路由):

path('test2',views.test2),

 include标签可以在加载模板的同时利用关键字with为模板传递变量。 

{% include "name_snippet.html" with person="Jane" greeting="Hello" %} 

 创建模板文件test3.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        引入模块:{% include 'test1.html' with data=100 %}
        当前模块:当前日期{% now "Y年f月j日 H:i:s"%}
    </p>
</body>
</html>

定义使用模板的视图文件:

def test3(request):
    data=90
    cls1='985'
    return render(request,'test3.html',{'data':data,'cls1':cls1})

 配置URL(根路由):

path('test3',views.test3),

若只希望使用提供的变量(或不使用变量)渲染上下文,需使用only选项。

{% include "name_snippet.html" with greeting="Hi" only %}

 创建模板文件test4.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>
        引入模块:{% include 'test1.html' with data=50 only %}
        当前模块:当前日期{% now "Y年f月j日 H:i:s"%}
    </p>
</body>
</html>

定义使用模板的视图文件:

def test4(request):
    data=90
    cls1='985'
    return render(request,'test4.html',{'data':data,'cls1':cls1})

  配置URL(根路由):

path('test4',views.test4),

七.自定义过滤器和标签

自定义的过滤器和标签通常位于应用目录中的包templatetags,在templatetags包中创建文件,在文件中自定义过滤器和标签。

1.自定义过滤器
第一步:创建新的应用booklist
python manage.py startapp booklist
第二步:在booklist创建文件夹templateags

 第三步:在templateags中创建filters.py
import datetime
#为了使自定义过滤器和标签生效,templatetags下的过滤器文件必须包含模块级变量register
from django import template
register = template.Library()
def sum(value, arg):
    return value + arg
register.filter('sum',sum)
@register.filter(name='examp')
def examp(value, arg):
    return str(value) + str(arg)
@register.filter
def examp(value, arg):
    return str(value) + str(arg)

需要说明的是,模板系统旨在展示内容,而非规定程序逻辑,自定义过滤器与标签时也应尽量遵循此宗旨。下面将分别介绍如何自定义过滤器和标签,以及如何使用自定义的过滤器和标签。 

第四步:在templates文件下创建demo.html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>demo51</title>
	</head>
	<body>
    <p>
        add1:{
   
   {a|add:'32'}},<br>
        add2:{
   
   {b|add:'second}'},<br>
        addslashes:{
   
   {c|addslashes}},<br>
        capfirst:{
   
   {d|capfirst}},<br>
        cut:{
   
   {f|cut:" "}},<br>
        date:{
   
   {g|date:"y月x日"}},<br>
        default:{
   
   {h|default:"35"}},<br>
        dictsort:{
   
   {i|dictsort:"age"}},<br>
        escape:{
   
   {j|escape}},<br>
        {% load filters %}
                filter:{
   
   {data|examp:4}}
                filter2:{
   
   {data|examp:5}}
    </p>
	</body>
<html>
第五步:写入视图函数views.py 
from django.shortcuts import render
from datetime import datetime
# Create your views here.
def demo(request):
    add1=[1,2,3]
    add2=[4,5,6]
    time=datetime.now()
    value=[ {'name':'张三','age':19},
            {'name':'李四','age':32},
            {'name':'王五','age':21},]
    c={'a':66,'b':add1,'second':add2,'c':"This is my compture.",'d':"laura",'f':"he ll o world",'g':time,'h':"",'i':value,'j':'<a&sd>','data':4}
    return render(request,'demo5.html',c)
 第六步:配置路由
path('demo',views.demo)

 2.自定义标签

simple_tag()是django.template.Library的一个方法,它接收一个包含任意个参数的函数,将其包装后注册到模板系统中。

第一步:写入templateages中的filters.py文件
import datetime
from django import template
register = template.Library()
def get_current_time(timezone, format_string):
    return datetime.datetime.now(timezone).strftime(format_string)
@register.simple_tag(takes_context=True)
def current_time(context, format_string):
    timezone = context['timezone']
    # get_current_time()是自定义的获取当前时间的方法
    return get_current_time(timezone, format_string)
第二步: 写入视图函数views.py
from django.shortcuts import render
from datetime import datetime
from dateutil import tz

def demo1(request):
    context = {
        "format_string": "%b %d %Y %H:%M:%S",
        # "timezone": tz.gettz('Asia/Shanghai'),
        "timezone": tz.gettz('Europe/London'),
    }
    return render(request, 'demo1.html', context)
第三步:配置根路由
path('demo1',views.demo1),
第四步:在文件夹templates中建立demo1.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="custom-label">

        {% load filters %}
        
        {% current_time format_string %}
       
       </div>
</body>
</html>
 

 下载插件

pip install python-dateutil

 八.模板继承

模板继承机制使用模板系统中的block标签和extends标签实现,其中block标签标识与继承机制相关的代码块,extends指定子模板所继承的模板。子模板可以通过继承获取父模板中的内容。

父模块{%block%}标签,子模块用{extend%}标签。

父模块(base.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{block title%}页面</title>
</head>
<body>
    {%block header%}
    <h1>标题</h1>
    {%endblock header%}
    {%block main %}
    <h2>页面内容</h2>
    {% endblock %}
    <br><br><br>
    {% block footer%}
        <div class="footer no-mp">
            <div class="foot_link">
                <a href="#" id="">关于我们</a>
                <span>|</span>
                <a href="#">联系我们</a>
                <span>|</span>
                <a href="#">招聘人才</a>
                <span>|</span>
                <a href="#">友情链接</a>
            </div>
            <p>CopyRiht @2019 北京小鱼商业股份有限公司 All Rights Reserved</p>
            <p>电话:010-****888 京ICP备******8号</p>
        </div>
        {%endblock%}
</body>
</html>

子模块(detail.html): 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {% extends 'base.html'%}
    {%block title %}
    列表页面
    {%endblock%}
    {%block header%}
    <h1>书单</h1>
    {%endblock header%}
    {%block main%}
    <a href="#">1.《鲁迅作品全集》</a><br>
    <a href="#">2.《秋雨散文集》</a><br>
    <a href="#">1.《黑暗森林》</a><br>
    <a href="#">1.《月亮与六便士》</a><br>
    {% endblock main %}
</body>
</html>

配置视图文件(views.py):

from django.shortcuts import render

# Create your views here.
def show_detail(request):
    return render(request,'detail.html')

def show_base(request):
    return render(request,'base.html')

配置路由文件(urls.py):

from django .urls import path
from .import views

urlpatterns = [
   path('show_detail',views.show_detail),
   path('show_base',views.show_base),
]

 

猜你喜欢

转载自blog.csdn.net/2201_76041915/article/details/134718745