• Django 2.0 学习(13):Django模板继承和静态文件


    Django模板继承和静态文件

    模板继承(extend)

    Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中的全部元素,并且可以定义能够被子模板覆盖的blocks。为了容易理解模板继承,我们先写一个模板:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Replaceable template{% endblock %}</title>
    </head>
    <body>
        <div id="sidebar">
            {% block sidebar %}
            <ul>
                <li><a href="/">Home</a> </li>
                <li><a href="/blog">Blog</a> </li>
            </ul>
            {% endblock %}
        </div>
        
        <div id="content">
            {% block content %}{% endblock %}
        </div>
    </body>
    </html>
    

    这个模板,我们把它叫做base.html,它定义了一个可以用于两列排版页面的简单HTML骨架。"子模板"可以用它们的内容填充空白的blocks。在这个例子中,block标签定义了三个可以被子模板内容填充的block,block告诉模板引擎:子模板可能会覆盖掉模板中的这些位置。

    接下来,我们再写一个子模板:

    {% extends "polls/base.html" %}        # 模板路径根据项目或者app的路径来写,笔者这里的模板位于app中
    
    {% block title %}Child template{% endblock %}
    
    {% block content %}
        {% for entry in blog_entries %}
            <h3>{{ entry.title }}</h3>
            <p>{{ entry.body }}</p>
        {% endfor %}
    {% endblock %}
    

    extends标签是这里的关键,它告诉模板引擎这个模板继承了另一个模板。当模板系统处理这个模板时,首先定位父模板--此例中,就是"base.html"。那时模板引擎注意到base.html中的三个block标签,并用子模板中的内容来替换这些block。根据blog_entries的值,子模板输出的内容会是下面的内容:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="style.css" />
        <title>Child template</title>
    </head>
     
    <body>
        <div id="sidebar">
            <ul>
                <li><a href="/">Home</a></li>
                <li><a href="/blog/">Blog</a></li>
            </ul>
        </div>
     
        <div id="content">
            <h2>Entry one</h2>
            <p>This is my first entry.</p>
     
            <h2>Entry two</h2>
            <p>This is my second entry.</p>
        </div>
    </body>
    </html>
    

    注意:子模板并没有定义sidebar block,所以系统使用了父模板中的值。父模板的{% block %}标签中的内容总是被用作备选内容。这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如:部分范围内的导航。

    说明:

    1.如果在模板中使用{% extends %}标签,它必须是模板中的第一个标签,其他的任何情况下,模板继承都将无法工作;
    2.在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的block,所以,我们可以在大多数>block中填充合理的默认内容,然后,只定义我们需要的那一个。多一点钩子总比少一点好;
    3.如果发现我们在大量的模板中复制内容,那就意味着我们应该把内容移动到父模板中的一个{% block %}中;
    4.有时候,想在父模板的基础上再添加点其他的,而不是完全覆盖父模板的内容,那么我们只需要在想要填充的块里,再加上 >{{ block.super }}语句,我们就可以把父模板里的东西给留下来,如:

    父模板中的
    {% block title %}Parent template{% endblock %}
    
    如果我们只想子模板的结果是在后面添加一个!,则只需要在子模板中写成
    {% block title %}
        {{ block.super }}!
    {% endblock %}
    

    5.为了更好的可读性,也可以给我们的 {% endblock %} 标签一个 名字 。例如:

    {% block content %}
    ...
    {% endblock content %} 
    

    6.在大型模板中,这个方法可以帮助我们清楚的看到哪个 {% block %}标签被关闭了;

    最后,请注意我们不能在一个模版中定义多个相同名字的 block 标签。这个限制的存在是因为block标签的作用是“双向”的。这个意思是,block标签不仅提供了一个坑去填,它还在父模版中定义了填坑的内容。如果在一个模版中有两个名字一样的 block 标签,子模版的父模版将不知道使用哪个block的内容。

    注意:模板一般放在app下的templates中,Django会自动去这个文件夹中找。但 假如我们每个app的templates中都有一个 index.html,当我们在views.py中使用的时候,直接写一个 render(request, 'index.html'),Django 能不能找到当前 app 的 templates 文件夹中的 index.html 文件夹呢?(答案是不一定能,有可能找错)

    Django模板查找机制:Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码,只在当前 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。这就需要把每个app中的 templates 文件夹中再建一个 app 的名称,仅和该app相关的模板放在 app/templates/app/ 目录下面。这样在使用的时候,有app作为名称的一部分,就不会混淆。

    模板include

    假如我们有以下模板index.html,代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <div>网页公共头部部分</div>
    
    <h2> 网页body部分 </h2>
    
    <div>网页公共底部部分</div>
    
    </body>
    </html>
    

    做过web开发的同学都知道大部分网页的公共头部,公共底部部分代码每个页面都一样,那么就应该将其单独拿出做为一个html, 这样修改这部分代码时候,不需要每个页面都修改, 所以在django中我们可以这么做:
    top.html

    <div>网页公共头部部分</div>
    

    bottom.html

    <div>网页公共底部部分</div>
    

    index.html

    <!DOCTYPE html>  
    <html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>Title</title>  
    </head>  
    <body>  
      
    {% include 'top.html' %}  
      
    <h2> 网页body部分 </h2>  
      
    {% include 'bottom.html' %}  
      
    </body>  
    </html>
    

    我们可以使用Django模板引擎的include语法,来将单独的页面包含到当前模板页面中。有同学有疑问,那我们通过视图传递给模板的上下文,在被包含的模板中可以使用吗?可以直接使用,假如我们的视图函数如下:

    def index(request):  
        return render(request, 'polls/index.html', {'a': 100, 'b': 200})
    

    该Django视图函数,传递给模板并渲染模板。

    top.html修改如下:

    <div>网页公共头部部分:{{ a }}</div>      # 这样使用没有任何问题
    

    我这里有这样的一个问题,假如所有的页面都使用共同的头部top.html, 可能针对1.html 2.html 3.html所使用的头部有些样式不一样,所需top.html:

    <div classs='acss'>网页公共头部部分</div>  
    

    但是对于5.html, 6.html使用的头部样式为:

    <div class='bcss'>网页公共头部部分</div>  
    

    很显然,如果直接通过include方式包含公共头部,会导致一些页面显示问题。既然部分参数不一样,include允许我们传递参数给被include的模板,我们可以使用with语法,那么问题解决如下:

    {{ % include 'top.html' with mycss='acss' % }}  
    

    top.html修改如下:

    <div class='{{mycss}}'>网页公共头部部分</div> 
    

    被包含模板中部分参数,由我们include的时候动态指定,那么top.html就不会因为细微差别而编写多份代码了。

    静态文件配置

    我们自己导入的一些页面相关的包就叫做静态文件

    • 在app目录中先创建static目录;
    • 在static目录里面导入我们的JS、CSS、Jquery和Bootstrap等;
    • 在项目settings.py中添加一些配置;
    STATIC_URL = '/static/'   #这个配置就相当于下面配置的别名,如果这里的名字修改了就按照这里的名字去导入
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,"static")  #E:day68static 找到static路径
    ]
    
    • 导入网页相关图片、CSS、JS、Jquery等
    <link rel = "stysheet",href= "/static/index.css/"> 
    
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    
  • 相关阅读:
    Kotlin Native
    大数据技术原理与应用【点个赞】
    TypeScript的概要和简介
    Windows 10 运行原生Bash【Ubuntu】
    Kotlin的参考资料
    Javascript前端和JAVA后端对加密库的处理实例
    bootstrap杂记
    原生JS实现各种经典网页特效——Banner图滚动、选项卡切换、广告弹窗等
    博文目录 | 杰瑞教育原创系列文章目录一览
    MUI框架开发HTML5手机APP(二)--页面跳转传值&底部选项卡切换
  • 原文地址:https://www.cnblogs.com/love9527/p/9082725.html
Copyright © 2020-2023  润新知