Django模板Tamplates

Django模板templates

Html是一个静态的语言,里面没法传一些动态参数,也就是就一个写死的html页面。 想实现在一个固定的html样式,传入不同的参数,就可以用django的模板传参。

1.  模板传参

先在HelloWorld 项目下的helloApp应用下,新建一个templates文件夹(Python Package),

再在templates下新建一个saber.html文件,模板变量用 {{变量名称}} 来表示。

HelloWorld/helloApp/templates/saber.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
<h1>恭迎吾王{{name}}</h1>
</body>
</html>

接下来需要向Django说明模板文件的路径,在HelloWorld/HelloWorld/settings.py修改 TEMPLATES 中的 DIRS [os.path.join(BASE_DIR, 'helloApp/templates')]如下所示:

注:BAS_EDIR的值在setting.py文件的上面已定义为项目的路径,所以添加模板的路径时需要带上应用的路径。

HelloWorld/HelloWorld/settings.py 文件:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'helloApp/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',
            ],
        },
    },
]

接着,修改views.py,增加一个新的对象,用于向模板提交数据:

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
from django.http import HttpResponse,Http404
# Create your views here.
def saber(request):
    context = {}
    context['name'] = '阿尔托莉雅'
    return render(request,'saber.html',context)

这里使用 render 来替代之前使用的 HttpResponse。render 还使用了一个字典 context 作为参数。context 字典中元素的键值 name 对应了模板中的变量 {{name}}

然后,urls.py 添加访问路径:

HelloWorld/helloApp/views.py 文件代码:

from django.conf.urls import url
from django.urls import re_path,path
from . import views
from helloApp import views as view      #引入文件名同名,可重命名
urlpatterns = [
    path('saber/',view.saber)
]

 再次访问 http://127.0.0.1:8000/saber,可以看到页面展示:恭迎吾王阿尔托莉雅

 2. 模板标签

 2.1 变量

django的模板里变量取值是通过句点语法来取值即 . 符号。 模板语法:

view文件里:{"HTML变量名": "views变量名"}

HTML文件里:{{ 变量名 }}

取值的对象可以是字符串、int类型、list列表、字典键值对,也可以是一个类的实例对象。

  • string字符串和int类型:通过key名直接取值,如{{ name }}
  • list类型:通过下班取值,如 {{ fancy.0 } {{ fancy.1 }} {{ fancy.2 }}
  • dict类型:通过 .keyname取值,如 { {blog.url }}
  • 类的方法:不带参数的方法,通过点方法取值,如 {{ myblog.fensi }}

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    context = {
        "name":"阿尔托莉雅",
        "n_name":"亚瑟王",
        "age":20,
        "fancy":["python","django","pytest"],
        "blog":{
            "url":"https:partner.huawei.com",
            "img":"http://partner.huawei.com/ePartner/apigateway/com.huawei.channelsales.echannel.echannel2.0:ePartner_comservice/ePartner/commonservice/servlet/public/file?url=/ha-i/448_spklp.png"
        }
    }
    class Myblog():
        def __init__(self):
            self.name = "吉尔伽美什"
            self.age = 1000
        def guanzhu(self):
            return 200
        def fensi(self):
            return 10000
    myblog = Myblog()       #实例
    context["myblog"] = myblog
    return render(request,'saber.html',context=context)

 HelloWorld/helloApp/templates/saber.html 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="referrer" content="no-referrer" />
    <title>吾王Saber</title>
</head>
<body>
<div>
    <h1 class='display_name'> {{ name }} </h1>
    <div>
        <p class="text_gray"><span>姓名:</span>{{n_name}}</p>
        <p class="text_gray"><span>年龄:</span>{{age}}</p>
        <p class="text_gray"><span>感兴趣的技术:</span>{{fancy.0}}、{{fancy.1}}、{{fancy.2}}</p>
    </div>
</div>
<h1 class="display_name">通过字典对象取值</h1>
<div>
    <p class="text_gray"><span>华为地址</span><a href="{{blog.url}}">{{blog.url}}</a></p>
    <p class="text_gray"><span>鲲鹏图片</span><img src="{{blog.img}}" style="height: 50px;"></p>
</div>
<h1 class="display_name">通过属性、方法取值</h1>
<p class="text_gray"><span>名称:</span>{{myblog.name}}</p>
<p class="text_gray"><span>关注数:</span>{{myblog.guanzhu}}</p>
<p class="text_gray"><span>粉丝数:</span>{{myblog.fensi}}</p>
</body>
</html>

再次访问 http://127.0.0.1:8000/saber,可以看到页面展示:

2.1.1 变量之字符串

引用变量为字符串:通过key名直接取值,如{{ name }}

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_name = '兰斯洛特'
    return render(request,'saber.html',{"name":view_name})

HelloWorld/helloApp/templates/saber.html 的变量行代码:

<h1>恭迎吾王{{name}}</h1>

再次访问 http://127.0.0.1:8000/saber,可以看到页面展示:恭迎吾王兰斯洛特

2.1.2 变量之列表

引用变量为列表,取列表中的数据:可以用  .   索引下标取出对应的元素

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_list = ["阿尔托莉雅","兰斯洛特","高文","杰兰特","加雷思"]
    return render(request,'saber.html',{"view_list":view_list})

HelloWorld/helloApp/templates/saber.html 文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
<p>亚瑟王及骑士们:{{view_list}}</p>
<p>亚瑟王:{{view_list.0}}</p> 
</body>
</html>

再次访问 http://127.0.0.1:8000/saber,可以看到页面展示:

2.1.3 变量之字典

引用变量为字典,取字典中的数据:可以用   .   索引下标取出对应的元素

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_dict = {"name":"兰斯洛特","develop":"圆桌骑士"}
    return render(request,'saber.html',{"view_dict":view_dict})

HelloWorld/helloApp/templates/saber.html 文件body部分修改:

<body>
<p>兰斯洛特:{{view_dict}}</p>
<p>兰斯洛特:{{view_dict.develop}}</p>
</body>

再次访问 http://127.0.0.1:8000/saber,可以看到页面展示:

2.2 过滤器

模板过滤器可以在变量被显示之前修改它,过滤器用管道字符 | ,模板语法:

{{ 变量名 | 过滤器:可选参数 }}

lower和upper

{{ name | lower }}   #{{ name }} 变量被过滤器lower 处理后,文本大写转换为小写

过滤管道可以被“套接”,即:一个过滤器管道的输出,又可以作为下一个管道的输入:

{{ my_list | first | upper }}  # 获取第一个元素并转化为大写

first           输出列表中的第一个值         {{ value | first }}

last            输出列表中最后一个值         {{ value | last }}

join           连接列表的值                        {{ value | join:"arg"}}

有些过滤器有参数,过滤器的参数跟随在冒号之后并且总是以引号包含。如:

truncatewords和truncatechars

  如果字符串包含的字符总个数多于指定的字符数量,则会截断掉后面的部分。截断的字符串以…结尾

{{ bio | truncatewords:"30" }}    # 显示变量bio的前30个词(词以空格识别)

{{ bio | truncatechars:"30" }}    # 显示变量bio的前30字符(最后一个用…)

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
from django.http import HttpResponse,Http404
# Create your views here.
def saber(request):
    dic = {"name":"lichKing", "develop":"HAPPY New year", 'num':[100,200,300],
           "bio":"my name is saber, I from dabuliedian, I well be the king for AESE"}
    return render(request,'saber.html',{'dic':dic})

HelloWorld/helloApp/templates/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
    <p>部门转小写:{{ dic.develop | lower}}</p>
    <p>名字取第一个转大写:{{ dic.name | first | upper }}</p>
    <p>bio前10词:{{ dic.bio | truncatewords:"10" }}</p>
    <p>bio前10字符:{{ dic.bio | truncatechars:"10" }}</p>
</body>
</html>

访问 http://127.0.0.1:8000/saber,可以看到页面展示:

部门转小写:happy new year

名字取第一个转大写:L

bio前10词:my name is saber, I from dabuliedian, I well be …

bio前10字符:my name i…

其他过滤器:

  • addslashes :  添加反斜杠到任何反斜杠、单引号或者双引号前面。
  • length : 返回变量的长度。
  • date :  按指定的格式字符串参数格式化 date 或者 datetime 对象,实例:{{ pub_date | date:"F j, Y" }}

default

  default为变量提供一个默认值。

  如果views传的变量的布尔值是false,则使用指定的默认值。这些值为false:0  0.0  False  0j  ""  []  ()  set()  {}  None

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    name = 0
    render(request,'saber.html',{'name':name})

HelloWorld/helloApp/templates/saber.html 文件代码:

<p>传的值为false时展示:{{ name | default:"那就交给在下了。" }}</p>

访问 http://127.0.0.1:8000/saber,页面展示:传的值为false时展示:那就交给在下了。

length

  length返回对象的长度,适用于字符串和列表。

  字典返回的是键值对的数量,集合返回的是去重后的长度。

  {{ name | length }}

filesizeformat

  filesizeformat以更易读的方式显示文件的大小(即’13KB’,’4.1MB’,’102byte’等)。

  释:字符串类型数字、数值类型数字都会当做byte去转换为byte、KB、MB等,非数字字符串转为0yte,其他类型会报错。

  {{ num | filesizeformat }}

data

  data根据给定格式对一个日期变量进行格式化。格式  Y-m-d H:i:s  返回 年-月-日 时:分:秒 的格式时间。

  {{ time | date:"Y-m-d" }}

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
from django.http import HttpResponse,Http404
# Create your views here.
def saber(request):
    import datetime
    nowTime = datetime.datetime.now()
    return render(request,'saber.html',{'time':nowTime})

HelloWorld/helloApp/templates/saber.html 文件代码:

<body>
<p>现在的时间是:{{time|date:'Y-M-D H:i:s'}}</p>
<p>现在的时间是:{{time|date:'y-m-d h:i:s'}}</p>
<p>现在的时间是:{{time|date:'Y-m-d H:i:s'}}</p>	   #常用的格式
<p>现在的时间是:{{time|date:'Y-m-d'}}</p>
<p>现在的时间是:{{time|date:'H:i:s'}}</p>
<p>现在的时间是:{{time|date:'F J,Y'}}</p>
</body>

访问 http://127.0.0.1:8000/saber,页面展示:

现在的时间是:2021-Mar-Sun 16:12:47

现在的时间是:21-03-07 04:12:47

现在的时间是:2021-03-07 16:12:47

现在的时间是:2021-03-07

现在的时间是:16:12:47

现在的时间是:March J,2021

safe

  safe将字符串标记为安全,不需要转义。

  要保证views.py传过来的数据绝对安全,才能用safe。和后端views.py的mark_safe效果相同。

  Django会自动对views.py传道HTML文件中的标签语法进行转义,令其语法失效。加safe过滤器是告诉Django该数据是安全的,不必对其进行转义,可让该数据语义生效。

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_str = "<a href='https://www.runoob.com/'>点击跳转</a>"
    return render(request,'saber.html',{'view_str':view_str})

HelloWorld/helloApp/templates/saber.html 文件代码:

<p>这是runoob入口:{{ view_str | safe }}</p>

访问 http://127.0.0.1:8000/saber,页面展示:

这是runoob入口:点击跳转

2.3 if/else 标签

基本语法格式:

{% if condition %}
     ... display
{% endif %}

 或:

{% if condition1 %}
   ... display 1
{% elif condition2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

根据条件判断是否输出,if/else支持嵌套。

{% if %}标签接受andornot关键字来对多个变量做判断,或对变量取反(not)。如:

{% if athlete_list and coach_list %}
     athletes 和 coaches 变量都是可用的。
{% endif %}

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    views_num = 88
    return render(request,'saber.html',{'num':views_num})

HelloWorld/helloApp/templates/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
    {% if num > 90 and num <= 100 %}
        优秀
    {% elif num > 60 and num <= 90 %}
        合格
    {% else %}
        一边玩去~
    {% endif %}
</body>
</html>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面展示:

合格

2.4 for 标签

{% for %} 允许我们在一个序列上迭代。与Python的for语句类似,循环语法是for X in Y

每一次循环中,模板系统会渲染在{% for %}{% endfor %}之间的所有内容。

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

给标签增加一个reversed使该列表被反向迭代:

{% for athlete in athlete_list reversed %}
...
{% endfor %}

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    views_list = ['帝落','仙古','乱古','荒古']
    return render(request,'saber.html',{'views_list':views_list})

HelloWorld/helloApp/templates/saber.html 文件代码:

<body>
    {% for i in views_list %}
        {{i}}时代
    {% endfor %}
</body>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面展示:

帝落时代 仙古时代 乱古时代 荒古时代

遍历字典:

可以直接用 字典.items 方法,用变量的解包分别获取键和值。

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    views_dict = {"name":"吉尔伽美什","age":"1000"}
    return render(request,'saber.html',{'views_dict':views_dict})

HelloWorld/helloApp/templates/saber.html 文件代码:

<body>
    {% for i,j in views_dict.items %}
        {{i}}----{{j}}
    {% endfor %}
</body>

再访问访问 http://127.0.0.1:8000/runoob,可以看到页面展示:

name----吉尔伽美什 age----1000

{% for %}标签里可以通过{{ forloop }}变量获取循环序号。

{% for %}循环内部,可以访问一个名为forloop的模板变量,这个变量有若干个属性,通过他们可以获知循环进程的一些信息。

  • counter: 顺序获取循环序号,从 1 开始计算
  • counter0: 顺序获取循环序号,从 0 开始计算
  • revcounter: 倒叙获取循环序号,结尾序号为 1
  • revcounter0: 倒叙获取循环序号,结尾序号为 0
  • first(一般配合if标签使用): 第一条数据返回 True,其他数据返回 False
  • last(一般配合if标签使用): 最后一条数据返回 True,其他数据返回 False
  • parentloop: 在嵌套循环中,forloop.parentloop引用父级循环的forloop对象

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_list = ["a","b","c","d","e"]
    return render(request,'saber.html',{'view_list':view_list})

HelloWorld/helloApp/templates/saber.html 文件代码:

<ul>
    {% for i in view_list %}
        <li>{{ forloop.counter }}</li>
    {% endfor %}
</ul>
  • 1
  • 2
  • 3
  • 4
  • 5
<ul>
    {% for i in view_list %}
        <li>{{ forloop.counter0 }}</li>
    {% endfor %}
</ul>
  • 0
  • 1
  • 2
  • 3
  • 4
<ul>
    {% for i in view_list %}
        <li>{{ forloop.revcounter }}</li>
    {% endfor %}
</ul>
  • 5
  • 4
  • 3
  • 2
  • 1
<ul>
    {% for i in view_list %}
        <li>{{ forloop.revcounter0 }}</li>
    {% endfor %}
</ul>
  • 4
  • 3
  • 2
  • 1
  • 0
<ul>
    {% for i in view_list %}
        <li>{{ forloop.first }}</li>
    {% endfor %}
</ul>
  • True
  • False
  • False
  • False
  • False
<ul>
    {% for i in view_list %}
        <li>{{ forloop.last }}</li>
    {% endfor %}
</ul>
  • False
  • False
  • False
  • False
  • True

{% empty %}

  可选的{% empty %}从句:在循环为空时执行(即in后面的参数布尔值为False)

HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_list = []
    return render(request,'saber.html',{'view_list':view_list})

HelloWorld/helloApp/templates/saber.html 文件代码:

<body>
    {% for i in views_list %}
        {{ forloop.counter0 }}
    {% empty %}
        空空如也~
    {% endfor %}
</body>

访问 http://127.0.0.1:8000/runoob,可以看到页面展示:空空如也~

可以嵌套使用 {% for %} 标签:

{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}

2.5 ifequal/ifnotequal 标签

{% ifequal %} 标签比较两个值,当他们相等时,显示在 {% ifequal %} {% endifequal %} 之中的所有值。

<!-- 比较user和currentuser -->
{% ifequal user currentuser %}
    <h1>Welcome!</h1>
{% endifequal %}

和 {% if %} 类似,{% ifequal %} 支持可选的 {% else %} 标签:

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

2.6 注释标签

  注释使用 {# #}

{# 这是一个注释 #}

2.7 include标签

  网站不同页面,顶部、底部内容差不多,就可把这些公共的部分单独出来,用include实现。

{% include %}标签允许在模板中包含其他的模块的内容。

{% include "nav.html" %}

例子:如下,网站的每个页面都有顶部导航,body正文,底部导航这三块内容:

HelloWorld/helloApp/templates/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
<section>
    <h1>顶部导航</h1>
    <p>恭迎吾王</p><hr>
</section>
<section>
    <h1>body正文</h1>
    <p>正文内容:亚瑟王</p>
</section>
<section>
    <br><br><br><hr>
    <h1>底部导航</h1>
    <p>底部一些友情链接,网站导航,版权</p>
</section>
</body>
</html>

把头部和底部单独抽出来:

HelloWorld/helloApp/templates/top.html 文件代码:

<section>
    <h1>顶部导航</h1>
    <p>恭迎吾王</p><hr>
</section>

HelloWorld/helloApp/templates/end.html 文件代码:

<section>
    <br><br><br><hr>
    <h1>底部导航</h1>
    <p>底部一些友情链接,网站导航,版权</p>
</section>

HelloWorld/helloApp/templates/saber.html 文件代码:使用include标签调用头部和底部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
{% include "top.html" %}
<section>
    <h1>body正文</h1>
    <p>正文内容:亚瑟王</p>
</section>
{% include "end.html" %}
</body>
</html>

使用之后,打开http://127.0.0.1:8000/saber展示跟原来的是一样的。

带参数:公共部分top.html和end.html里面也可以传变量,如:

HelloWorld/helloApp/templates/top.html 文件代码:

<section>
    <h1>顶部导航</h1>
    <p>恭迎吾王{{ view_doct .name}}</p><hr>
</section>

 对应视图函数HelloWorld/helloApp/views.py 文件代码:

from django.shortcuts import render
def saber(request):
    view_doct = {"name":"亚瑟王"}
    return render(request,'saber.html',{"view_doct":view_doct})

2.8 csrf_token 标签

  csrf_token用于form表单中,作用是跨站请求伪造保护。

如果不用{% csrf_token %}标签,在用form表单时,要再次跳转页面会报403权限错误。用了{% csrf_token %}标签,在form表单提交数据时,才会成功。

解析:首先,向服务器发送请求,获取登录页面,此时中间件csrf会自动生成一个隐藏input标签,该标签里的value属性的值是一个随机的字符串,用户获取到登录页面的同时也获取到了这个隐藏的input标签。

然后,等用户需要用到form表单提交数据的时候,会携带这个input标签一起提交给中间件csrf,原因是form表单提交数据时,会包括所有的input标签,中间件csrf接收到数据时,会判断,这个随机字符串是不是第一次发给用户的那个,如果是,则数据提交成功,如果不是,则返回403权限错误。

3. 自定义标签和过滤器

3.1 自定义标签

  django的模板里有很多标签可快速实现一些功能,如 {% url url_name %} 可快捷导入一个本地url地址。

Django的模板有很多内置的过滤器,可满足常见需求,无法满足时需要写一些过滤器。

1、在应用目录下创建templatetags目录(与templates目录同级,目录名只能是templatetags)。

2、在templatetags目录下创建任意py标签文件,如:mytags.py

     在templatetags目录下创建任意py过滤器文件,如:myfilter.py

注:需确保在setting.py已注册过你的app(INSTALLED_APPS 里添加过app名称'helloApp' )

常见标签语法:

  • {% for %}                    循环输出变量的内容
  • {% if %}                      对变量条件判断
  • {% crsf_token %}        生成crsf_token值,用于防护跨站请求伪造攻击
  • {% url %}                    引用路由配置地址,生成相应的url地址
  • {% with %}                 将变量名重命名
  • {% load %}                导入django标签库
  • {% static %}               加载静态资源内容
  • {% extends %}           模板继承
  • {% block xxx %}         重写与父类模板的block内容
  • {% include xxx %}     导入模板 文件内容,代码复用

3.2 编写自定义标签或自定义过滤器

  利用装饰器 @register.filter 自定义过滤器,利用装饰器 @register.simple_tag 自定义标签。如:

myreplace()函数:替换value的指定arg字符为~,定义的过滤器名称 name="replace"

HelloWorld/helloApp/templatetags/myfilter.py 文件代码:

from django import template
register = template.Library()

@register.filter(name='replace')
def myreplace(value,arg):
    return value.replace(arg,'~')

@register.filter(name='lvji')
def myfilter1(v1,v2):
    return v1*v2

注意:装饰器的参数最多只能有2个。

get_current_time()函数:获取当前时间,定义标签名为current_time

HelloWorld/helloApp/templatetags/mytag.py 文件代码:

from django import template
import time
register = template.Library()  # register的名字是固定的,不可改变

@register.simple_tag(name='current_time')
def get_current_time():
    timstr = time.strftime("%Y-%m-%d %H:%M:%S")
    return timstr

@register.simple_tag(name='qiuji')
def mytag1(v1,v2,v3):
    return v1*v2*v3

from django.utils.safestring import mark_safe
@register.simple_tag(name="myhtml")
def my_html(v1,v2):
    temp_html = "<input type='text' id='%s' class='%s' />" %(v1,v2)
    return mark_safe(temp_html)
# 语义化标签:导入mark_safe
# 定义标签时,用上mark_safe方法,令标签语义化,相当于 jQuery 中的 html() 方法。
# 和前端HTML文件中的过滤器safe效果一样。 

视图函数:定义变量(看需要)

HelloWorld/helloApp /views.py 文件代码:

from django.shortcuts import render
def saber(request):
    hello = "Hello World!"
    return render(request,'saber.html',{'hello':hello})

模板引用: 在模板中引用自定义过滤器或标签,必须先load加载自己定义的过滤器或标签文件:

HelloWorld/helloApp/template/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
{% load myfilter %}
{% load mytag %}
<div>
    <p><span>hello:</span>{{ hello | replace:"!"}}</p>
    <p class="text_gray"><span>系统当前时间:</span>{% current_time %}</p>
    <p>{{11 | lvji:22}}</p>
    <p>{% qiuji 11 22 33 %}</p>
    <p>{% myhtml "zzz" "xxx" %}</p>
</div>
</body>
</html>

打开http://127.0.0.1:8000/saber.html后,展示:

 

在HTML中使用mark_safe函数的自定义标签,在页面中动态创建标签。

4. 配置静态文件

1、在项目根目录下创建statics目录。

2、在statics目录下创建css目录、js目录、images目录、plugins目录,分别放css文件、js文件、图片、插件。

3、在setting.py文件的最下方配置添加以下配置:

STATIC_URL = '/static/'     # 别名
STATIC_ROOT = os.path.join(BASE_DIR,'statics')
# 设置图片等静态文件的路径
STATICFILES_DIRS = (
    ('css',os.path.join(STATIC_ROOT,'css').replace('\\','/')),
    ('js',os.path.join(STATIC_ROOT,'js').replace('\\','/')),
    ('images',os.path.join(STATIC_ROOT,'images').replace('\\','/')),
)

4、在urls.py文件开头引入并添加以下:

from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib import staticfiles
...
# 设置静态文件路径
urlpatterns += staticfiles_urlpatterns()

5、在模板中从静态目录中引入图片:(注意图片前缀是/static/images/)

HelloWorld/helloApp/templates/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
 <img src="/static/images/huang.jpg" alt="huang">
</body>
</html>

再访问访问 http://127.0.0.1:8000/saber 就可以看到图片展示出来了。

其他:把bootstrap框架放入插件目录plugins下。在HTML文件的head标签中引入bootstrap。

<link rel="stylesheet" href="/static/plugins/bootstrap-5.0.0-beta2-dist/css/bootstrap.css">

5. 模板继承

  模板可以用继承的方式来实现复用,减少冗余内容。

网站的奠基导航栏切换不同页面,导航部分是不变的,只是页面的主体内容变了,于是可以写个父模板,其他子页面继承母模板就可以。

父模板用于防止可重复利用的内容,子模板继承父模板的内容,并放置自己的内容。

父模板

  可在父模板中添加多个块标签,每个块标签取不同的的名称

标签block … endblock:父模板中的预留区域,该区域留给子模板填充差异性的内容,不同预留区域名字不能相同。

{% block 名称 %} 
    预留给子模板的区域,可以设置设置默认内容
{% endblock 名称 %}

 {% block content %} {% endblock content %}            content是块标签名称

子模板

  子模板使用标签extends继承父模板,填充block块标签内容,指定对应的名称就可以了。 

{% extends "父模板路径" %}

 如果父模板中block有默认内容,子模板不填充的话,就显示默认的内容。如果都没设置,就为空。

子模板设置父模板预留区域的内容:

{ % block 名称 % }
    内容 
{% endblock 名称 %}

 例子1:

HelloWorld/helloApp/templates/base.html 代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>父模板</title>
</head>
<body>
    <h1>顶部导航</h1>
    <p>一念花开,君临天下</p>
    {% block mainbody %}
        <p>original</p>
    {% endblock %}
</body>
</html>

HelloWorld/helloApp/templates/saber.html 代码:子模板填充

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
    {% extends "base.html" %}
    {% block mainbody %}
        <p>继承了base.html文件</p>
    {% endblock%}
</body>
</html>

 

HelloWorld/helloApp/templates/saber.html 代码:子模板不填充

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
    {% extends "base.html" %}
</body>
</html>

 例子2:

HelloWorld/HelloWorld/urls.py 文件:

from django.conf.urls import url
from django.urls import re_path,path
from . import views
from helloApp import views as view      #引入文件名同名,可重命名
urlpatterns = [
    url('^saber/$',view.saber)
]
 HelloWorld/helloApp/views.py 文件代码:
from django.shortcuts import render
def saber(request):
    context = {
        "ads": ["完美世界","遮天","圣墟"],
        "name": "临兵斗者皆组列前行"
        }
    return render(request,'saber.html',context)

 

HelloWorld/helloApp/templates/base.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"><title>父模板</title>
</head>
<body>
<section>
    <h1>顶部导航</h1>
    <p>一念花开,君临天下</p><hr>
</section>
<!--这是注释。block是一个块标签,content是标签名称-->
{% block content %}{% endblock content %}
<p>----------遮天三部曲----------</p>
<!--这是注释。block是一个块标签,ad是标签名称-->
{% block ad %}
    <p>默认值,如果子页面无填充,展示此内容</p>
{% endblock ad %}
<section>
    <br><br><br><hr><h1>底部导航</h1>
    <p>底部一些友情链接,网站导航,版权啊</p>
</section>
</body></html>
 

HelloWorld/helloApp/templates/saber.html 文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>吾王Saber</title>
</head>
<body>
<!--注释,extends继承base.html页面-->
{% extends "base.html" %}
{% block content %}
    <p>这里是content块的填充内容</p>
{% endblock content %}
{% block ad %}
    {% for i in ads %}
        <li>{{i}}</li>
    {% endfor %}
    &nbsp;&nbsp;&nbsp;&nbsp;{{name}}
{% endblock ad %}
</body>
</html>

打开http://127.0.0.1:8000/saber.html后,展示:

 

posted on 2022-08-01 15:44  云初见  阅读(60)  评论(0编辑  收藏  举报