在我们的Django 入门教程中,我向您展示了如何启动和运行 Django 站点。不过,我们渲染的模板非常基础。
这绝对不是您希望网站的样子。
你如何让你的网站看起来更好?简单的!添加一些样式。在本教程中,我将向您展示如何向 Django 模板添加一些 CSS 和 JavaScript,以使它们看起来更好。为此,您首先需要了解 Django 中静态文件的概念。
设置 Django 项目
让我们设置我们的测试 Django 项目。首先,创建一个名为的文件夹projects
,这是我们的应用程序所在的位置。
mkdir projects && cd projects
在里面projects
,让virtualenv
我们用来为我们的应用程序的依赖项创建一个环境。
virtualenv env --python python3
注意:如果您还没有virtualenv
安装,请使用命令安装它pip install virtualenv
。
完成后,通过运行 activate shell 脚本来激活环境。
source env/bin/activate
如果该命令有效,您应该会(env)
在终端上看到一个提示。
#(env)~/projects
$
一切看起来都很好?惊人的!现在让我们使用pip
安装Django
到我们的环境中。
#(env)~/projects
$ pip install django
该命令应该将 Django 安装到您的环境中。在撰写本文时,Django 版本是1.10.4
.
然后我们将调用django-admin
脚本来创建我们的 Django 应用程序。让我们这样做:
#(env)~/projects
$ django-admin startproject djangotemplates
如果你检查你的projects
文件夹结构,djangotemplates
除了env
我们之前创建的文件夹之外,你现在应该有一个由 Django 创建的新文件夹。
cd
进入djangotemplates
。
您的文件夹结构现在应该类似于:
djangotemplates
--djangotemplates
----**init**.py
----settings.py
----urls.py
----wsgi.py
--manage.py
全部做完?您现在可以开始了!
管理静态文件的设置
静态文件包括 CSS、JavaScript 和您可能希望与网站一起提供的图像等内容。Django 对如何包含静态文件非常有意见。在本文中,我将展示如何向 Django 应用程序添加静态文件。
打开settings.py
内部djangotemplates
文件夹中的文件。在文件的最底部,您应该看到以下几行:
# djangotemplates/djangotemplates/settings.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
这一行告诉 Djangolocalhost:8000
在搜索静态文件时将静态附加到基本 url(在我们的例子中)。在 Django 中,你static
几乎可以在任何你想要的地方拥有一个文件夹。您甚至可以拥有多个static
文件夹,例如每个应用程序中都有一个。但是,为简单起见,我将仅使用static
项目文件夹根目录中的一个文件夹。我们稍后会创建一个。现在,让我们在settings.py
文件中添加一些行,使其看起来像这样。
# djangotemplates/djangotemplates/settings.py
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
STATIC_URL = '/static/'
# Add these new lines
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
该STATICFILES_DIRS
元组告诉Django去哪里寻找那些不依赖于特定的应用静态文件。在这种情况下,我们只是告诉 Djangostatic
在我们的根文件夹中调用的文件夹中查找静态文件,而不仅仅是在我们的应用程序中。
Django 还提供了一种将静态文件收集到一个地方的机制,以便可以轻松地提供它们。使用该collectstatic
命令,Django 会在您的应用程序中查找所有静态文件,并在您告诉它的任何位置收集它们,即STATIC_ROOT
. 在我们的例子中,我们告诉 Django,当我们运行时python manage.py collectstatic
,将所有静态文件收集到staticfiles
我们项目根目录中名为的文件夹中。此功能对于提供静态文件非常方便,尤其是在生产环境中。
应用程序设置
创建一个static
与内部djangotemplates
文件夹和manage.py
文件在同一级别上调用的文件夹。你现在应该有这个结构:
djangotemplates
--djangotemplates
----**init**.py
----settings.py
----urls.py
----wsgi.py
--static
--manage.py
在此文件夹中,我们将拥有我们选择编写的任何自定义 CSS 和 JS。关于这一点,让我们在静态文件夹中添加两个文件夹来保存我们的文件,一个css
名为js
. 在里面css
,创建一个名为main.css
. main.js
在js
文件夹中添加一个。您的静态文件夹现在应如下所示:
--static
----css
------main.cs
----js
------main.js
完成后,让我们创建一个名为example
我们将使用的新 Django 应用程序。你还记得怎么做吗?别担心,这很简单。
#(env)~/projects/djangotemplates
$ python manage.py startapp example
一旦做到这一点,你应该有一个文件夹,名为example
一起djangotemplates
和static
。当然,您仍然应该能够看到该manage.py
文件。
djangotemplates
--djangotemplates
----**init**.py
----settings.py
----urls.py
----wsgi.py
--example
--static
--manage.py
我们需要将我们的新应用程序告诉 Django。转到内部djangotemplates
文件夹,打开settings.py
并查找INSTALLED_APPS
. example
在其他包含的应用程序下添加。
# djangotemplates/djangotemplates/settings.py
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'example', # Add this line
]
回顾一下,我们现在有以下文件夹结构:
djangotemplates
--djangotemplates
----**init**.py
----settings.py
----urls.py
----wsgi.py
--example
----migrations
------**init**.py
----admin.py
----apps.py
----models.py
----tests.py
----views.py
--static
----css
------main.cs
----js
------main.js
--manage.py
网址定义
让我们定义一个 URL 以转到我们的新应用程序。让我们进行编辑djangotemplates/djangotemplates/urls.py
以实现这一点。
# djangotemplates/djangotemplates/urls.py
from django.conf.urls import url, include # Add include to the imports here
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('example.urls')) # tell django to read urls.py in example app
]
之后,在example
app 文件夹中,创建一个名为的新文件urls.py
并添加以下代码:
# djangotemplates/example/urls.py
from django.conf.urls import url
from example import views
urlpatterns = [
url(r'^$', views.HomePageView.as_view(), name='home'), # Notice the URL has been named
url(r'^about/$', views.AboutPageView.as_view(), name='about'),
]
我们刚刚编写的代码告诉 Django 将空路由(即 localhost:8000)与名为 的视图相匹配HomePageView
,并将路由/about/
与名为 的视图相匹配AboutPageView
。请记住,Django 视图接收 HTTP 请求并返回 HTTP 响应。在我们的例子中,我们将使用一个TemplateView
返回主页模板,另一个返回关于页面。为此,在您的example
app 文件夹中,创建另一个名为templates
. 在新templates
文件夹中,创建两个名为index.html
和 的新文件about.html
。您的example
应用程序文件夹现在应该具有以下结构:
--example
----migrations
------**init**.py
----templates
------index.html
------about.html
----admin.py
----apps.py
----models.py
----tests.py
----urls.py
----views.py
在 中index.html
,粘贴以下代码:
<!-- djangotemplates/example/templates/index.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome Home</title>
</head>
<body>
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</p>
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
</body>
</html>
将此代码添加到about.html
:
<!-- djangotemplates/example/templates/about.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About Us</title>
</head>
<body>
<p>
We are a group of Django enthusiasts with the following idiosyncrasies:
<ol>
<li>We only eat bananas on Saturdays.</li>
<li>We love making playing football on rainy days.</li>
</ol>
</p>
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
</body>
</html>
注意如何我们指的是我们的链接Go Home
,并About This Site
在我们的模板。我们可以使用 Django 的自动 URL 反向查找,因为我们在urls.py
. 整洁,嗯!
我们将在下一节中看到这段代码的效果。
连接视图
让我们添加最终代码来提供我们的模板。我们需要为此进行编辑djangotemplates/example/views.py
。
# djangotemplates/example/views.py
from django.shortcuts import render
from django.views.generic import TemplateView # Import TemplateView
# Add the two views we have been talking about all this time :)
class HomePageView(TemplateView):
template_name = "index.html"
class AboutPageView(TemplateView):
template_name = "about.html"
现在我们可以运行我们的应用程序了。我们首先需要进行 Django 的默认迁移,因为这是我们第一次运行我们的应用程序。
#(env)~/projects/djangotemplates
$ python manage.py migrate
完成后,启动您的服务器。
#(env)~/projects/djangotemplates
$ python manage.py runserver
打开浏览器并导航到http://localhost:8000
。您应该能够看到我们的主页。
单击底部的链接应该能够在页面之间导航。这是关于页面:
模板继承
让我们将注意力转移到example
app 文件夹内的模板文件夹。目前,它包含两个模板,index.html
和about.html
.
我们希望这两个模板都包含一些 CSS。Django 允许我们创建一个它们都将从中继承的基本模板,而不是在它们中重写相同的代码。这可以防止我们在需要修改共享的任何内容时在模板中编写大量重复代码。
现在让我们创建基本模板。创建一个名为文件base.html
在djangotemplates/example/templates
。在里面写下这段代码:
<!-- djangotemplates/example/templates/base.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Django Sample Site - {% block title %}{% endblock %}
</title>
<script src="{% static 'js/main.js' %}"></script> <!-- This is how to include a static file -->
<link rel="stylesheet" href="{% static 'css/main.css' %}" type="text/css" />
</head>
<body>
<div class="container">
{% block pagecontent %}
{% endblock %}
</div>
</body>
</html>
文件中的第一行{% load static %}
使用 Django 的特殊模板标记语法来告诉模板引擎使用static
此模板中文件夹中的文件。
在标题标签中,我们使用了一个 Django 块。这意味着在任何继承自该基本模板的 Django 模板中,位于名为块的任何 HTMLtitle
都将插入到标题块中。body 标签的pagecontent
块也是如此。如果这听起来令人困惑,请不要担心。您很快就会看到它的实际效果。
如果您没有运行 Django 服务器,请通过python manage.py runserver
在终端中执行来运行它。转到http://localhost:8000。您应该会看到之前的模板。
现在编辑index.html
模板以从基本模板继承。
<!-- djangotemplates/example/templates/index.html -->
{% extends 'base.html' %} <!-- Add this for inheritance -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome Home</title>
</head>
<body>
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</p>
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
</body>
</html>
在浏览器中重新加载页面。什么都没有出现!这是因为 Django 期望您的内容写入我们在基本模板中定义的块中,以便它们可以被呈现。编辑index.html
以添加块:
<!-- djangotemplates/example/templates/index.html -->
{% extends 'base.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome Home {% endblock %}</title>
</head>
<body>
{% block pagecontent %}
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</p>
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
{% endblock %}
</body>
</html>
在浏览器中重新加载页面,瞧!您的内容应该会再次出现!
我们还可以编辑about.html
模板以使用相同的模板。
<!-- djangotemplates/example/templates/about.html -->
{% extends 'base.html' %} <!-- Add this for inheritance -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}About Us {% endblock %}</title>
</head>
<body>
{% block pagecontent %}
<p>
We are a group of Django enthusiasts with the following idiosyncrasies:
<ol>
<li>We only eat bananas on Saturdays.</li>
<li>We love making playing football on rainy days.</li>
</ol>
</p>
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
{% endblock %}
</body>
</html>
您现在应该在“关于”页面上看到:
这和以前完全一样!
但是,现在因为两个模板都继承自一个基本模板,所以我可以轻松地设置它们的样式。main.css
在您的css
文件夹中打开并添加以下样式:
.container {
background: #eac656;
margin: 10 10 10 10;
border: 3px solid black;
}
这将为我们加载内容的容器 div 设置样式。刷新浏览器。你应该看到这个:
主页:
关于页面:
使用视图中的数据渲染模板
您可以使用 Django 的模板引擎以非常强大的方式显示数据。在本节中,我将创建一个将数据传递到模板的 Django 视图。然后,我将向您展示如何访问模板中的数据并将其显示给用户。
首先,views.py
在example
应用程序文件夹中打开。我们将添加一个新视图以将数据提供到我们尚未存在的data.html
模板中。将views.py
文件修改为如下所示:
# djangotemplates/example/views.py
from django.shortcuts import render
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name = "index.html"
class AboutPageView(TemplateView):
template_name = "about.html"
# Add this view
class DataPageView(TemplateView):
def get(self, request, **kwargs):
# we will pass this context object into the
# template so that we can access the data
# list in the template
context = {
'data': [
{
'name': 'Celeb 1',
'worth': '3567892'
},
{
'name': 'Celeb 2',
'worth': '23000000'
},
{
'name': 'Celeb 3',
'worth': '1000007'
},
{
'name': 'Celeb 4',
'worth': '456789'
},
{
'name': 'Celeb 5',
'worth': '7890000'
},
{
'name': 'Celeb 6',
'worth': '12000456'
},
{
'name': 'Celeb 7',
'worth': '896000'
},
{
'name': 'Celeb 8',
'worth': '670000'
}
]
}
return render(request, 'data.html', context)
我们使用与渲染其他模板相同的视图。但是,我们现在将一个context
对象传递给 render 方法。上下文中定义的键值对将在正在呈现的模板中可用,我们可以像任何其他列表一样遍历它们。
要完成此操作,请转到应用程序中的urls.py
文件howdy
并为我们的新视图添加 URL 模式,使其如下所示:
# djangotemplates/example/urls.py
from django.conf.urls import url
from example import views
urlpatterns = [
url(r'^$', views.HomePageView.as_view(), name='home'),
url(r'^about/$', views.AboutPageView.as_view(), name='about'),
url(r'^data/$', views.DataPageView.as_view(), name='data'), # Add this URL pattern
]
最后,让我们创建模板。在该templates
文件夹中,创建一个名为的文件data.html
并将此代码写入其中。
<!-- djangotemplates/example/templates/data.html -->
{% extends 'base.html' %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% block pagecontent %}
<div class="table-div">
<!-- We will display our data in a normal HTML table using Django's
template for-loop to generate our table rows for us-->
<table class="table">
<thead>
<tr>
<th>Celebrity Name</th>
<th>Net Worth</th>
</tr>
</thead>
<tbody>
{% for celebrity in data %}
<tr>
<td>{{ celebrity.name }}</td>
<td>{{ celebrity.worth }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
</body>
</html>
在 中data.html
,您可以看到我们使用本质上是一个 for 循环来遍历数据列表。Django 模板中的值绑定是使用{{}}
大括号完成的,就像在 AngularJS 中一样。
在您的服务器运行时,转到http://localhost:8000/data/
查看模板。
将片段包含到您的模板中
我们现在有三个模板index.html
,about.html
和data.html
。让我们使用一个简单的导航栏将它们链接在一起。首先,让我们在另一个 HTML 模板中编写导航栏的代码。
在example
应用程序内的模板文件夹中,创建一个名为partials
. 在里面,创建一个名为nav-bar.html
. 模板文件夹结构现在应该是这样的:
templates
----index.html
----about.html
----data.html
----partials
------nav-bar.html
编辑nav-bar.html
部分,使其包含以下代码:
<!-- djangotemplates/example/templates/partials/nav-bar.html -->
<div class="nav">
<a href="{% url 'home' %}">Go Home</a>
<a href="{% url 'about' %}">About This Site</a>
<a href="{% url 'data' %}">View Data</a>
</div>
在模板中包含片段非常简单。我们使用includes
Django 模板引擎提供的关键字。继续并修改index.html
为:
<!-- djangotemplates/example/templates/index.html -->
{% extends 'base.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome Home {% endblock %}</title>
</head>
<body>
{% block pagecontent %}
<p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</p>
{% include 'partials/nav-bar.html' %} <!--Add this-->
<!-- Remove these two lines -- >
<!-- <a href="{% url 'home' %}">Go Home</a> -->
<!-- <a href="{% url 'about' %}">About This Site</a> -->
{% endblock %}
</body>
</html>
修改about.html
为:
<!-- djangotemplates/example/templates/about.html -->
{% extends 'base.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}About Us {% endblock %}</title>
</head>
<body>
{% block pagecontent %}
<p>
We are a group of Django enthusiasts with the following idiosyncrasies:
<ol>
<li>We only eat bananas on Saturdays.</li>
<li>We love making playing football on rainy days.</li>
</ol>
</p>
{% include 'partials/nav-bar.html' %} <!--Add this-->
<!-- Remove these two lines -- >
<!-- <a href="{% url 'home' %}">Go Home</a> -->
<!-- <a href="{% url 'about' %}">About This Site</a> -->
{% endblock %}
</body>
</html>
最后修改data.html
为:
<!-- djangotemplates/example/templates/data.html -->
{% extends 'base.html' %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% block pagecontent %}
<div class="table-div">
<table class="table">
<thead>
<tr>
<th>Celebrity Name</th>
<th>Net Worth</th>
</tr>
</thead>
<tbody>
{% for celebrity in data %}
<tr>
<td>{{ celebrity.name }}</td>
<td>{{ celebrity.worth }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include 'partials/nav-bar.html' %} <!--Add this-->
{% endblock %}
</body>
</html>
是时候看看我们的作品了!打开浏览器并导航到http://localhost:8000
。你应该看到这个:
所有页面现在都与导航栏链接,因此您可以轻松地来回浏览它们,只需编写最少的代码。这是data.html
模板:
这里是about.html
:
注意:我添加了以下 CSS 来对导航栏中的链接进行分类。随意使用它或玩你自己的风格:
// djangtotemplates/static/css/main.css
.container {
background: #eac656;
margin: 10 10 10 10;
border: 3px solid black;
}
.nav a {
background: #dedede;
}
过滤器
过滤器接收通过管道传送到它们的数据并以格式化的方式输出它。Django 模板可以访问humanize
过滤器集合,这使数据更具可读性。让我们使用其中一些过滤器使数据模板中的名人净值字段更具可读性。
要使用 Django 的人性化过滤器,您首先需要编辑一些设置。打开djangotemplates/settings.py
并将INSTALLED_APPS
列表编辑为:
# djangotemplates/djangotemplates/settings.py
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize', # Add this line. Don't forget the trailing comma
'example',
]
我们现在可以在模板中使用过滤器。我们将使用intcomma
过滤器来添加大量逗号以使其更易于阅读。让我们修改data.html
成这样:
<!-- djangotemplates/example/templates/data.html -->
{% extends 'base.html' %}
{% load humanize %} <!-- Add this-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% block pagecontent %}
<div class="table-div">
<table class="table">
<thead>
<tr>
<th>Celebrity Name</th>
<th>Net Worth</th>
</tr>
</thead>
<tbody>
{% for celebrity in data %}
<tr>
<td>{{ celebrity.name }}</td>
<td>$ {{ celebrity.worth | intcomma }}</td> <!--Modify this line-->
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include 'partials/nav-bar.html' %}
{% endblock %}
</body>
</html>
当您转到 时http://localhost:8000/data/
,您现在应该有一个更友好的净资产值列表:
humanize
包中包含更多过滤器。在此处阅读有关它们的信息
收集静态文件
还记得我们说过收集静态文件吗?尝试以下命令:
python manage.py collectstatic
您应该会看到如下提示:
You have requested to collect static files at the destination
location as specified in your settings:
/Users/amos/projects/djangotemplates/staticfiles
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel:
说吧yes
。
此命令将告诉 Django 遍历您所有的项目文件夹,查找所有静态文件并将它们存储在一个位置(我们在设置中定义的静态根)。这非常有效,尤其是当您将站点部署到生产环境时。
当您运行该命令时collectstatic
,您应该会staticfiles
在项目文件夹的根目录中看到一个名为created的新文件夹。您可以通过编辑项目settings.py
文件中的静态根设置来将此位置更改为其他位置。要使用这些staticfiles
,在你的模板中你会说load staticfiles
而不是load static
。其他一切都与使用上一个static
文件夹相同。
结论
Congratulations on reaching the end of this tutorial! By now you should have a more detailed understanding of how Django templates work. If you need deeper information, remember the docs are your friend. You can find the full code for this tutorial here. Make sure to leave any thoughts, questions or concerns in the comments below.