母版页用于处理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">×
</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>