《Python编程:从入门到实践》笔记。
本篇将对Django项目做最后的完善。本篇也是这本书的最后一篇。
1. 前言
在本篇中,我们将:
- 使用Bootstrap库设置样式;
- 把项目部署到Heroku上。
2. 设置项目“学习笔记”的样式
之前关注的都是项目的功能,现在来为项目添加样式。
我们将使用
django-bootstrap3
来设置样式。首先请在虚拟环境中安装这个第三方库。
然后像之前在项目
settings.py
中注册我们自己编写的APP一样,注册
bootstrap3
这个应用程序。
还需要包含
django-bootstrap3
包含
jQuery
,在
settings.py
末尾添加如下代码:
-- snip --
LOGIN_URL = '/users/login/'
# django-bootstrap3的设置
BOOTSTRAP3 = {
"include_jquery": True,
}
2.1 修改base.html
2.1.1 定义HTML头部
实现访问项目的每个页面时,浏览器标题都现实这个网站的名称。另外还添加了一些在模板中使用Bootstrap所需的信息。删除
base.html
的全部代码,并添加如下代码:
{% load bootstrap3 %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Learning Log</title>
{% bootstrap_css %}
{% bootstrap_javascript %}
</head>
</html>
第12行使用了
django-bootstrap3
的一个自定义模板标签,它让Django包含所有的Bootstrap样式文件。第13行启用可能在页面中使用的所有交互式行为,如可折叠的导航栏。
2.1.2 定义导航栏
-- snip --
</head>
<body>
<!-- Static navbar -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#navbar" aria-expanded="false" aria-controls="navbar">
</button>
<a class="navbar-brand" href="{% url 'learning_logs:index' %}">Learning Log</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="{% url 'learning_logs:topics' %}">Topics</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li><a>Hello, {{ user.username }}.</a></li>
<li><a href="{% url 'users:logout' %}">log out</a></li>
{% else %}
<li><a href="{% url 'users:register' %}">register</a></li>
<li><a href="{% url 'users:login' %}">log in</a></li>
{% endif %}
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
</body>
</html>
navbar
、
navbar-default
和
navbar-static-top
是三个选择器,在
nav
块中的内容将根据选择器在Bootstrap中定义的样式规则来设置样式(额,
html
中选择器的概念有点忘了,不过不要紧,我们的任务并不是研究HTML)。在第20-28行中是我们之前编写的判断语句,只不过被放在了
ul
块中,并且设置了一个选择器
navbar-right
。
2.1.3 定义页面的主要部分
-- snip --
</head>
<body>
-- snip --
<div class="container">
<div class="page-header">
{% block header %}{% endblock %}
</div>
<div>
{% block content %}{% endblock %}
</div>
</div> <!-- /container -->
</body>
</html>
这部分包含一个
div
块,该块的
class
属性是
container
(容器),容器中包含两个元素:一个新增的
header
块和之前用到的
content
块。
header
块的内容告诉用户页面包含哪些信息以及用户可以在页面上执行哪些操作,其
class
属性值
page-header
将一系列样式应用于这个块。
base.html
的修改到此为止。
2.2 使用jumbotron设置主页样式
下面使用新定义的
header
块及另一个名为
jumbotron
的Bootstrap元素修改主页。
jumbotron
元素是一个大框,通常用于在主页中呈现项目的简要描述,修改
index.html
:
{% extends "learning_logs/base.html" %}
{% block header %}
<div class="jumbotron">
<h1>Track your learning.</h1>
</div>
{% endblock header %}
{% block content %}
<h2>
<a href="{% url 'users:register' %}">Register an account</a>to make your own
Learning Log, and list the topics you're learning about.
</h2>
<h2>
Whenever you learn something new about a topic, make an entry summarizing
what you've learned.
</h2>
{% endblock content %}
在
header
块中,我们用一个
jumbotron
元素来修饰一条简短的标语,让首次访问者大致知道网站功能。随后再
content
块中描述了两种主要操作。下图是实际效果:
2.3 设置登录页面样式
现在的代码改进了登录页面的整体外观(因为修改了
base.html
),现在来改进登录表单,修改
login.html
:
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2>Log in to your account.</h2>
{% endblock header %}
{% block content %}
<form class="form" method="post" action="{% url 'users:login' %}">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button class="btn btn-primary" name="submit">log in</button>
{% endbuttons %}
<input type="hidden" name="next" value="{% url 'learning_logs:index' %}"/>
</form>
{% endblock content %}
第2行代码加载了
bootstrap3
模板标签;
header
块描述这个页面时做什么的;
删除了之前的
if form.errors
代码块,因为
django-bootstrap3
位自动管理表单错误;
form
块中添加了属性
“form"
,然后使用标签模板
bootstrap_form
来显示表单,这个标签替换掉了之前的
form.as_p
;
button
也使用Bootstrap样式进行了替换,下面是实际效果图:
2.4 设置new_topic.html页面样式
{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}
{% block header %}
<h2>Add a new topic:</h2>
{% endblock header %}
{% block content %}
<form class="form" action="{% url 'learning_logs:new_topic' %}" method="post">
{% csrf_token %}
{% bootstrap_form %}
{% buttons %}
<button class="btn btn-primary" name="submit">add topic</button>
{% endbuttons %}
</form>
{% endblock content %}
上面的修改大多都类似于对
login.html
的修改。
2.5 设置topics.html页面样式
{% extends "learning_logs/base.html" %}
{% block header %}
<h1>Topics</h1>
{% endblock header %}
{% block content %}
<ul>
{% for topic in topics %}
<li>
<h3>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</h3>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
<h3><a href="{% url 'learning_logs:new_topic' %}">Add a new topic:</a></h3>
{% endblock content %}
这里并没有加载
bootstrap3
,因为该文件中并没有使用任何
bootstrap3
自定义标签。
2.6 设置topic.html中条目的样式
topic
页面包含的内容比其他大部分页面都多,所以样式设置要多一些,我们将使用Bootstrap面板(
panel
)来突出每个条目。
{% extends "learning_logs/base.html" %}
{% block header %}
<h2>{{ topic }}</h2>
{% endblock header %}
{% block content %}
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
</p>
{% for entry in entries %}
<div class="panel panel-default">
<div class="panel-heading">
<h3>
{{ entry.date_added|date:"M d, Y H:i" }}
<small>
<a href="{% url 'learning_logs:edit_entry' entry.id %}">edit
entry</a>
</small>
</h3>
</div>
<div class="panel-body">
{{ entry.text|linebreaks }}
</div>
</div> <!-- panel -->
{% empty %}
<li>
There are no entries for this topic yet.
</li>
{% endfor %}
{% endblock content %}
只修改了样式,并没有修改Django代码。下图是实际效果: