Django中母版、组件、inclusion_tag的使用

  1. 云栖社区>
  2. 博客>
  3. 正文

Django中母版、组件、inclusion_tag的使用

slashboywang 2018-08-30 22:39:00 浏览801
展开阅读全文

母版页用于处理html页面相同部分内容,避免出现冗余代码

一、母版的使用:

  • 使用母版情况1:母板中定义页面专用的CSS块和JS块,方便子页面替换。
  • 使用母版情况2:多个页面有很多共同的代码段时可以将相同的代码段提取出来。
  • 使用方法:
    通过在母板中使用 {% block xxx %}来定义"块"。
    在子页面中继承母版 {% extends "xxx.html" %}
    通过母板中的命名块{% block page-main%}....{% endblock %}来对应替换母板中相应的位置。

代码示例:
母版--->base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>个人数据管理中心</title>
    <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-inverse" role="navigation">
    <div class="container-fluid">
        <div class="navbar-header">
            <a class="navbar-brand" href="#">个人数据管理中心</a>
        </div>
        <div>
        </div>
    </div>
</nav>
{% block page-main%}
{% endblock %}


{% block page-js %}
{% endblock %}
</body>
</html>

子内容-继承母版-->views.html

{% extends "base.html" %}
{% block page-main %}
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-info">
                    <div class="panel-heading">
                        <h4 style="display: inline-block">数据详情</h4>
                        <a href="{{ add_url }}">
                            <button class="btn btn-lg btn-info pull-right">添加数据</button>
                        </a>
                    </div>
                    <div class="panel-body">
                        <table class="table table-hover table-striped table-bordered">
                            <thead>
                            <tr>
                                {% for head in heads_list %}
                                    <td><h4>{{ head }}</h4></td>
                                {% endfor %}
                            </tr>
                            </thead>
                            <tbody>
                            {% for obj in obj_list %}
                                <tr>
                                    {% for field in obj %}
                                        <td>
                                            {{ field }}
                                        </td>
                                    {% endfor %}
                                </tr>
                            {% endfor %}
                            </tbody>
                        </table>
                    </div>
                </div>
                {{ page_html|safe }}
                <!------模态框开始-------->
                <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
                     aria-hidden="true">
                    <div class="modal-dialog">
                        <div class="modal-content">
                            <div class="modal-header">
                                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;
                                </button>
                                <h4 class="modal-title" id="myModalLabel">确认删除</h4>
                            </div>
                            <div class="modal-body">您确定要删除所选的数据吗???</div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                                <a id="del-success" href="">
                                    <button type="button" class="btn btn-primary">删除</button>
                                </a>
                            </div>
                        </div><!-- /.modal-content -->
                    </div><!-- /.modal -->
                </div>

                <!------模态框结束-------->

            </div>
        </div>
    </div>
{% endblock %}
{% block page-js %}
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script src="https://cdn.bootcss.com/bootstrap/2.3.2/js/bootstrap.js"></script>
    <script>
        $(function () {
            $(".delete-link").click(function () {
                var url = $(this).attr('href');
                $("#del-success").attr("href", url)
            })
        });
    </script>
{% endblock %}

子内容-继承母版-->addviews.html

{% extends "base.html" %}
{% block page-main %}
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-info">
                    <div class="panel-heading">
                        <h4>添加数据</h4>
                    </div>
                    <div class="panel-body">
                        <form action="" method="post" novalidate>
                            {% csrf_token %}
                            {% for field in form_obj %}
                                <div class="form-group">
                                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                    {{ field }}
                                    <span class="error pull-right" style="color: red">{{ field.errors.0 }}</span>
                                </div>
                            {% endfor %}
                            <input type="submit" class="btn btn-success">
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
{% endblock %}

二、组件的使用:

可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

{% include 'navbar.html' %}

组件和母版的区别:

  • 组件相当于是单拿出来独立的一部分,哪里需要插哪里,即插即用!!!
  • 母版相当于是一个整体的框架,将有差异的各个部分单留出空间来,以方便自定制内容的填充。

三、静态文件配置

简单地说就是:我们自己导入的一些包就叫做静态文件
配置的步骤:

  • 1、在全局中先创建一个static的包,
  • 2、在static里面导入我们的bootstrap,还是jquery等等...
  • 3、然后在settings.py中加上一些配置
STATIC_URL = '/static/'   #这个相当于给配置起的别名,如果这里的名字修改了就按照这里的名字去导入
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,"static")  #通过和项目根路径拼接得到static的路径
]
  • 4.1、普通导入css,js,jquery
<link rel = "stysheet",href= "/static/index.css/"> 
<link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
  • 4.2 动态导入(这种导入更加灵活)
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
  • 还可以用在一下地方:
{% load static %}
<img src="{% static "images/hi.jpg" %}" alt="Hi!" />
{% load static %}
<script src="{% static "mytest.js" %}"></script>
  • 某个文件多处被用到可以存为一个变量:
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>
  • get_static_prefix的使用
{% load static %}
<img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" />

或者

{% load static %}
{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />

四、inclusion_tag

类似于上面的组件,只不过他需要从后端得到数据才能完成渲染成功。多用于返回html代码片段
代码示例:

  • 第一步:在app下创建一个名为templatetags(必须是这个名字)文件夹。
  • 第二步:在这个文件夹下创建一个py文件,名字没要求。
  • 第三步:在py文件中先导入,在注册,代码是固定死的。
from django import template
register = template.Library()
  • 第四步:写视图函数得到页面所需要的数据,将数据return回来,
  • 第五步:给这个视图函数加上@register.inclusion_tag(filename='left_menu.html'),以指定html文件将数据传入。
  • 在需要用到自定义inclusion_tag的html文件中引入,引入固定规则为:
    通过使用{% load py文件名 %} {% 对应html文件名 py文件中的视图函数所需参数 %}的固定形式引用自定义的inclusion_tag。

l_menu.py文件示例:

from django import template
from blog import models
from datetime import datetime

register = template.Library()


@register.inclusion_tag(filename='left_menu.html')
def left_menu(username):
    # 通过用户信息找到当前用户的对象
    user_obj = models.UserInfo.objects.filter(username=username).first()
    # ORM操作查询当前用户对应的所有书籍
    article_list = models.Article.objects.filter(user=user_obj).order_by("create_time").reverse()
    # ORM操作查询当前用户对应的所有分类
    categorys = models.Category.objects.filter(blog=user_obj.blog)
    # ORM操作查询当前用户对应的blog的tags
    tags = models.Tag.objects.filter(blog=user_obj.blog)

    # 时间归档方式一
    #通过对所有对象的create_time字段的处理,通过列表的去重和计数得到对应的前端数据
    date_list = [datetime.strftime(obj.create_time, '%Y-%m') for obj in article_list]
    list2 = list(set(date_list))
    list2.sort(key=date_list.index)
    ret_date_list = [(i, date_list.count(i)) for i in list2]

    #时间归档方式二
    # 对当前blog的所有文章按照年月 分组 查询
    # 1. models.Article.objects.filter(user=user_obj)                   --> 查询出当前作者写的所有文章
    # 2. .extra(select={"y_m": "DATE_FORMAT(create_time, '%%Y-%%m')"}   --> 将所有文章的创建时间格式化成年-月的格式,方便后续分组
    # 3. .values("y_m").annotate(c=Count("id"))                         --> 用上一步时间格式化得到的y_m字段做分组,统计出每个分组对应的文章数
    # 4. .values("y_m", "c")                                            --> 把页面需要的日期归档和文章数字段取出来
    # archive_list = models.Article.objects.filter(user=user_obj).extra(
    #     select={"y_m": "DATE_FORMAT(create_time, '%%Y-%%m')"}
    # ).values("y_m").annotate(c=Count("id")).values("y_m", "c")

    return {
        'username': username,
        'categorys': categorys,
        'tags': tags,
        'ret_date_list': ret_date_list,
    }

left_menu.html示例:

<div class="panel panel-info">
    <div class="panel-heading">
        文章分类
    </div>
    <div class="panel-body">
        <ul class="list-group">
            {% for category in categorys %}
                <li class="list-group-item">
                    <a href="/blogcenter/{{ username }}/category/{{ category.title }}">
                        {{ category.title }}({{ category.article_set.all.count }})
                    </a>
                </li>
            {% endfor %}
        </ul>
    </div>
</div>

<div class="panel panel-success">
    <div class="panel-heading">
        标签
    </div>
    <div class="panel-body">

        <ul class="list-group">
            {% for tag in tags %}
                <li class="list-group-item">
                    <a href="/blogcenter/{{ username }}/tag/{{ tag.title }}">
                        {{ tag }}({{ tag.article_set.all.count }})
                    </a>
                </li>
            {% endfor %}
        </ul>
    </div>
</div>

<div class="panel panel-primary">
    <div class="panel-heading">
        日期归档
    </div>
    <div class="panel-body">
        <ul class="list-group">
            {% for date in ret_date_list %}
                <li class="list-group-item">
                    <a href="/blogcenter/{{ username }}/archive/{{ date.0 }}">
                        {{ date.0 }}({{ date.1 }})
                    </a>
                </li>
            {% endfor %}
        </ul>
    </div>
</div>

base.html文件示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>个人中心</title>
    <link rel="stylesheet" href="/static/bootstrap/bootstrap-3.3.7/css/bootstrap.css">
    <link rel="stylesheet" href="/static/css/mycss.css">
</head>
<body>
<div class="container-fluit">
    <div class="row">
        <!--左侧栏开始-->
        <div class="col-md-2">

      //通过使用{% load  py文件名 %}  {% 对应html文件名  py文件中的视图函数
      //所需参数 %}的固定形式引用自定义的inclusion_tag。
            {% load l_menu %}
            {% left_menu username %}
        </div>
        <!--左侧栏结束-->
        {% block page-main %}
        {% endblock page-main %}
    </div>
</div>
<script src="/static/js/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/bootstrap-3.3.7/js/bootstrap.js"></script>
{% block page-js %}
{% endblock page-js %}
</body>
</html>

网友评论

登录后评论
0/500
评论
slashboywang
+ 关注