本文学习如何通过Django使用Bootstrap。其实在之前好几个Django项目中已经尝试使用过了Bootstrap,而且都留有学习记录,我已经大概有了一个大的框架,那么本文就从头再走一遍流程,其实主要细节还是Bootstrap的常用的语法使用。除了基本流程,本文基于BBS+Blog项目进行学习,主要是完成其项目的模板的功能,顺带学习一下Bootstrap的内容。
我使用的Python版本为3.X,Bootstrap版本为3.3.31,Django版本为2.0。
模板语法不懂的可以参考博客:Django学习笔记(3)——表单,路由控制和模板语法的学习
1,下载及配置Bootstrap相关文件
点击:Bootstrap官网下载链接
我们选择第一个,或者第二个都可以:两者的区别就是源码内容更加完善,而用于生产的比较轻便。
我们可以看看两者的目录结构。
1.1,Bootstrap预编译版的基本文件结构:
预编译文件可以直接使用到任何web项目中。官方提供了编译好的CSS和JS(bootstrap.*)文件,还有经过压缩的CSS和JS(bootstrap.*)文件。同时还提供了CSS源码映射表(bootstrap.*.map),可以在某些浏览器的开发工具中使用。
1.2,Bootstrap源码的基本文件结构:
当然,有时候我们做测试的时候,也可以直接使用CDN。
1.3 Bootstrap的CDN
Bootstrap中文网为Bootstrap专门构建了免费的CDN加速服务,访问速度更快,加速效果更明显,没有速度和带宽限制,永久免费。
代码如下:
那所谓的CDN就是通过一个互联网部署在多个数据中心的大型分布式服务器系统。浏览器可以并行的从CDN下载文件,不需要从自己的服务器下载文件。这些文件不在同一个域中,不会受浏览器的限制(同时只能在一个域下载几个文件)。因此下载时不会一个一个排队。另外CDN会根据用户的位置和更快的路由速度来选择服务器下载文件。
优点:节省带宽,提高网站性能。
1.4 包含的内容
基本结构:Bootstrap 提供了一个带有网格系统,链接样式,背景的基本结构。
CSS:Bootstrap 自带以下特性:全局的CSS设置,定义基本的HTML元素样式,可扩展的class,以及一个先进的网格系统。
组件:Bootstrap 包含了十几个可重用的组件,其中包括以下组件:下拉菜单,按钮组,按钮下拉菜单,导航,导航条,路径导航,分页,排版,略缩图,警告对话框,进度条,媒体对象等。
JavaScript插件:Bootstrap包含了十几个自定义的jQuery插件。其中包括:模式对话框,标签页,滚动条,弹出框等。
定制:你可以定制Bootstrap的组件,Less变量 和jQuery插件来得到自己的版本。
1.5 放在项目中
我们将下载的Bootstrap-3.3.7 放在Django项目中的static目录下。我下载的是源码版本的。
其次,Bootstrap插件全部依赖于jQuery,因此jQuery必须在Bootstrap之前就引入。
2,在Django中配置Bootstrap内容
2.1 配置settings文件
我们打开Django的settings文件,在最下面添加配置,用于指定静态文件的搜索目录。只有指定静态文件的存放位置,才能在模板中正确引导他们。
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]
注意:STATIC_URL 和STATICFILES_DIRS 不同,可以说两者并没有什么联系。STATIC_URL主要是的是前端的URL搜索路径。而STATCIFILES_DIRS 主要是联系的后台静态文件的路径地址。
2.2 创建 base.html 模板
一个网站要有自己的统一风格和公共部分,可以将这部分内容集中到一个基础模板 base.html中,现在我们在根目录下的 template 中建一个 base.html 文件作为站点的基础模板。
在Bootstrap文档中,为我们提供了一个非常简单而且又实用的基础模板。我们可以拷贝这段代码,然后根据自己的需求对其进行改进即可。
下面是一个官网最基础的Bootstrap页面:
Bootstrap 101 Template 你好,世界!
然后我们修改部分内容,如下:
Title {{ blog.title }} 管理
{% block content %} {% endblock %}
- 如果需要引入静态文件的话,我们需要在模板中要加上
{% load staticfiles %}
之后,才可使用{% static 'path' %}
引用静态文件。 - HTML语法中,所有的内容都被标签包裹;标签及标签中的属性可以对内容进行排印、解释说明等作用。
标签内包含网页的元数据,是不会在页面内显示出来的。
标签内才是网页会显示的内容。
- 留意Bootstrap的css、js文件分别是如何引入的
- jquery.js 要在 bootstrap.js 前引入。**
2.3 改写article_detail.html内容
这里我们以article_detail.html为例进行改写,其他的就不一一列举。
我们可以查看其部分样式如下:
我们可以留意 {% block content %} 是如何与 base.html 进行对应起来的。
完整代码如下:
{% extends "base.html" %} {% block content %} {% csrf_token %}{% endblock %}{{ article_obj.title }}
{{ article_obj.content|safe }}{{ article_obj.up_count }}{{ article_obj.down_count }}
2.4 其中过程捋一捋
- 当我们通过
url
访问list.html
时,顶部的{% extends "base.html" %}
告诉Django:“这个文件是继承base.html
的,你去调用它吧。” - 于是Django就老老实实去渲染
base.html
文件: - (如果存在的话,不存在忽略这一步)其中的
{% include 'header.html' %}
表明这里需要加入header.html
的内容。 (如果存在的话,不存在忽略这一步){% include 'footer.html' %}
加入footer.html
的内容。{% block content %}{% endblock content %}
表明这里应该加入list.html
中的对应块的内容。
2.5 运行服务器
当我们按部就班的完成的所有流程,我们保存内容,运行开发服务器,可以在浏览器输入正确的URL地址,就能看到漂亮的页面。
展示一下,我做的一个简单的博客home页面
3,BBS+Blog博客系统首页模板语言的编写
3.1 设计博客系统首页——导航区域
导航条是我们的应用或者网站中作为导航页头的响应式基础组件。他们在移动设备上可以折叠(并且可关可开),且再视口(viewport)宽度增加时逐渐变为水平展开模式。
我们可以看到我的博客页面右上角,如果登录进去的话,如下:
如果没有登录的话,则显示的是下面这样的状态:
那么如何写一个差不多样式呢? 这里为了简单方便起见,我们使用Bootstrap的导航条代码。地址:请点我
那上面代码显示出来的前端页面如下:
我们将不需要的东西可以去掉,留下我们需要的,然后修改其中的语言。我们可以去Bootstrap中找到一个小人
然后添加到 index.html的模板中,最后修改得到如下效果:
3.2 设计博客系统首页——主体布局
当首页的导航区域设计完后,我们开始对主体布局,然后对尾部布局,这里简单起见,我们不打算写尾部布局。
我们打算将主页分为三部分,第一部分是目录区域,中间是代码,第三部分是广告栏区域。
我们这里主要学习第二部分内容的填充,所以我们将第一部分和第三部分用进度条表示。
第一部分和第三部分进度条的代码如下:
Panel heading without titlePanel contentPanel heading without titlePanel contentPanel heading without titlePanel content代码Panel heading without titlePanel contentPanel heading without titlePanel content
效果如下:
3.3 设计博客系统首页——文章列表渲染
那下面主要的任务就是文章列表的渲染,也就是中间的主要内容,包括文章的内容,点赞功能,评论功能。那主要功能就参考博客园首页,我随便截取了两篇博客,效果如下:
那这就是主体内容,主要分为博客题目,博客博主图片博客索引,和博主名称,发布于,加上如期,加上评论,阅读。
我们就按照这样的样式写即可,只不过把阅读变为点赞,因为后面我们要实现这样的效果。
所以我们这里主要分为两部分,一个是上面内容包括文章题目,头像,索引内容渲染,一个是下面,某某博主发表于什么时间,点赞,评论。
3.3.1 文章题目,头像,索引内容渲染
index.html
{% for article in article_list %}
{% endfor %}
views.py
def index(request): article_list = models.Article.objects.all() return render(request, 'index.html', locals())
前端页面展示:
3.3.2 文章点赞,评论渲染
那大体效果做好后,我们可以完成文章点赞,评论的效果。
代码如下:
{{ article.user.username }} 发布于 {{ article.create_time|date:'Y-m-d:H:i' }} 评论({{ article.comment_count }}) 点赞({{ article.up_count }})
我们可以去bootstrap中下载两个效果图,一个是评论,一个是点赞,下面是我随便选择的两个样式。
最后做出来的效果如下:
3.4 设计博客系统首页的完整代码展示
代码如下:
Title Panel heading without titlePanel contentPanel heading without titlePanel contentPanel heading without titlePanel content{% for article in article_list %}{{ article.title }}
{{ article.user.username }} 发布于 {{ article.create_time|date:'Y-m-d:H:i' }} 评论({{ article.comment_count }}) 点赞({{ article.up_count }})
{% endfor %}Panel heading without titlePanel contentPanel heading without titlePanel content
4,BBS+Blog博客系统个人站点页面模板语言的编写
4.1 个人站点页面的规划布局
那个人站点页面的话,我们希望做成和博客园差不多的效果,首先我们查看我的博客站点:
那我们也设置成类似的效果,有一个标题和设置,而我左边栏目设置为类似于博客园这种,我的标签,随笔分类,随机归档就够了。希望简单容易。
上面的标题也不设置这种一张背景,前面加点字这种,设置成
4.2 个人站点页面的渲染布局——标题栏设置
标题栏目我们就简单的设置为博客的名称和设置即可。
home_site.html的代码如下:
Title {{ blog.title }} 管理
视图如下:
4.3 个人站点页面的渲染布局——左边标签栏设置
左边标签栏我们打算设置为我的标签,随笔分类,随机归档就OK了。
代码如下:
我的标签{% for tag in tag_list %}{{ tag.0 }}({{ tag.1 }})
{% endfor %}随笔分类{% for cate in cate_list %}{{ cate.0 }}({{ cate.1 }})
{% endfor %}随笔归档{% for data in data_list %}{{ data.0 }}({{ data.1 }})
{% endfor %}{% for article in article_list %}{{ article.title }}
{{ article.desc }}发布于 {{ article.create_time|date:'Y-m-d:H:i' }} 评论({{ article.comment_count }}) 点赞({{ article.up_count }})
{% endfor %}
展示效果如下:
4.4 个人站点页面的完整代码及其效果展示
index.html代码如下:
{% extends 'base.html' %} {% block content %}{% for article in article_list %}{% endblock %}{{ article.title }}
{{ article.desc }}发布于 {{ article.create_time|date:"Y-m-d H:i" }} 评论({{ article.comment_count }}) 点赞({{ article.up_count }})
{% endfor %}
效果如下:
5 Django框架中的自定义模板标签(template.Library())
由于用了继承,会传相同参数导致代码复用,所以某一些标签(例如:菜单栏,css,js,以及一些复杂计算后的数据等)需要我们自定义。然后在指定的HTML中引用并显示。之所以要用到标签,主要作用就是想让一些内容在多个模板(HTML)中都要有,比如菜单栏。
我们绝对不想让每个视图函数(views)都写一次这些变量内容,所以可以继承一些页面的共同部分,提取出来搭配 base.html。那么如何做呢?
5.1 创建register变量
首先我们在blog这个APP下新建一个名为 templatetags 的文件夹,并在下面建一个名为 my_tags.py的文件,然后引入template包。其内容如下:
from django import template #注册我们自定义的标签,只有注册过的标签,系统才能认识你,这是固定写法 register = template.Library()
5.2 添加自定义标签,注册过滤器函数
由于需求是左边的栏目会重复使用,其中包括他的引用函数,在views里面也会重复使用,HTML代码也会重复使用。所以我们要是写了标签,就不需要重复再写其代码了。
我们将其视图函数中的函数和HTML中的重复代码提取出来,视图函数内容如下:
from django import template from django.db.models import Count from blog import models register = template.Library() @register.inclusion_tag("classification.html") def get_classification_style(username): user = models.UserInfo.objects.filter(username=username).first() blog = user.blog cate_list = models.Category.objects.filter(blog=blog).values("pk").annotate(c=Count("article__title")).values_list( "title", "c") tag_list = models.Tag.objects.filter(blog=blog).values("pk").annotate(c=Count("article")).values_list("title", "c") date_list = models.Article.objects.filter(user=user).extra( select={"y_m_date": "date_format(create_time,'%%Y/%%m')"}).values("y_m_date").annotate( c=Count("nid")).values_list("y_m_date", "c") return {"blog": blog, "cate_list": cate_list, "date_list": date_list, "tag_list": tag_list}
classification.html代码如下:
我的标签{% for tag in tag_list %} {% endfor %}随笔分类{% for cate in cate_list %} {% endfor %}随笔归档{% for date in date_list %} {% endfor %}
5.3 在 base.html代码里使用上述标签
标签相关方法指的是在html显示前,后台先进行预处理,和我们平常的方法相同,只不过这个方法是针对标签所定义的,,inclution_tag模板语法把参数传给 inclution_tag 渲染好公共部分后,直接返回 HTML 代码会更为方便。
那 base.html 里面引用如下:
{% block content %} {% endblock %}
我们使用 load my_tags引用。
5.4 注意
标签字符 [转义] 才能格式化出文章样式 safe 后台必须做一个筛选,否则加上 safe 可能会受到 xss 攻击。
{% extends 'base.html' %} {# 继承公共部分 #} {% block content %}{{ article_obj.title }}
{{ article_obj.content|safe }}{% endblock %}
评论树
评论列表
{% for comment in comment_list %}-
# {{ forloop.counter }}楼
{{ comment.create_time|date:"Y-m-d H:i" }}
{{ comment.user.username }}
回复
{% if comment.parent_comment_id %}
{% endif %}
{% endfor %}
{{ comment.parent_comment.user.username }}: {{ comment.parent_comment.content }}
{{ comment.content }}
发表评论
昵称:
评论内容: