Django 速成课程
更新版本请访问ceiphr.com。
介绍
这不是教程。本速成课程旨在帮助你快速上手,创建一个基本的 Django 网站,而无需深入探讨构建复杂 Web 应用程序所需的底层概念。在本速成课程的每个步骤中,我都会提供链接,解释你使用的工具和概念,以便你在创建第一个项目的同时,更好地理解 Django。
先决条件
掌握 Python、HTML、CSS和Unix 命令行基础知识。
只要你熟悉这些,就没问题了。
我们的目标
我们正在开发一个网站,用户可以在上面上传图片,并添加标题、日期和描述。就这么简单。
那么,Django是什么?
Django /JANG-oh/ — 一种工具(Web框架),最出名的是它能帮助人们快速创建简洁的网站,并且减少错误。
在 Django 中创建东西遵循以下模式:
- 模型——你如何存储数据。在这里,我们将告诉 Django 如何存储我们的图片、标题、日期和描述。
- 视图——项目思考的地方。在这里,我们的网站将根据模型获取存储的数据,并将其处理后呈现给用户。
- 模板——项目如何呈现其思考过程。视图将使用此模板,根据我们的模型显示其处理后的内容。
Django 的功能更复杂(也更有趣),但如果你是新手,目前只需要知道这些就够了。[深入讲解]
建立我们的项目
Windows 用户请注意: Windows 系统默认不包含 Unix 命令行,而 Unix 命令行是本速成课程的先决条件。Windows 10 2018 年 10 月更新提供了 Linux 子系统,例如 Ubuntu。请安装并配置 Linux 子系统以使用 Unix 命令行。
我们将使用您电脑的终端来设置 Python 环境和 Django。让我们在电脑的Documents文件夹中创建项目,所以请输入以下命令:
cd ~/Documents
python3 -m venv django_cc
python3 -m venv django_cc我们将在项目文件夹内创建一个虚拟环境,django_cc这样我们为项目安装的所有组件就不会干扰您系统上的其他任何内容。[深入分析]
接下来,我们将进入项目文件夹,启用新的 Python 环境并安装 Django。
cd django_cc
source bin/activate
pip install django
source bin/activate将会激活我们创建的虚拟环境。这意味着当我们安装 Django 时,它不会安装到整个系统,而只会安装到我们的项目中。pip install django将会使用 Python 的包管理器来安装最新版本的 Django。
Django 安装完成后,我们可以使用一些新命令。首先,让我们在 Django 中创建一个项目,迁移开发数据库,最后首次启动本地开发服务器,以确保一切操作正确。
django-admin startproject django_cc
cd django_cc
python3 manage.py migrate
python3 manage.py runserver
django-admin start project django_cc这是告诉 Django 创建我们项目的根目录,所有其他部分(例如 Django 应用)都将连接到这里。我们也会在这里找到manage.py用于与 Django 交互的文件。[深入分析]
python3 manage.py migrate用于通知 Django 我们的模型已发生更改。由于我们的项目刚刚启动,这将是我们的初始迁移,用于建立 Django 自行创建的模型(例如帐户、活动日志、权限等)。[深入分析]
python3 manage.py runserver我们将启动开发服务器,用于测试我们的项目。
要查看开发服务器的运行情况,请在浏览器中访问127.0.0.1:8000。此时应该会显示 Django 启动页面:
数据库
接下来,打开你最喜欢的文本编辑器或 Python IDE,因为我们将深入学习 Django。我们将首先创建一个 Django 应用,并在其中编写本项目的所有模型。
python manage.py startapp blog
为了让核心项目识别这个应用,我们需要让它知道我们的blog应用存在,方法是像这样将其添加到INSTALLED_APPS项目中django_cc/settings.py:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
媒体文件支持
让我们在文件底部添加以下内容settings.py,以便 Django 知道将我们上传的图片等媒体文件存储在哪里:
# Media file support
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
我们需要对模板文件夹进行同样的操作,将默认值DIRS更新[os.path.join(BASE_DIR, 'templates')]为[]:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
我们还需要在文件底部添加一些导入语句和一个条件语句,django_cc/urls.py以便开发服务器上可以访问这些文件:
from django.conf.urls import url
from django.contrib import admin
# Add these imports for static file support and to get
# directory details from Django's settings.py
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
# Add this to enable media file support on the development server
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
太好了,我们的项目现在已经搭建完毕,可以开始编写模型了。
编写我们的模型
在我们的新blog应用程序中,我们会找到一个models.py文件,用于编写数据库模型。该类Post将作为我们的第一个模型,用于上传包含图片、标题、描述和发布日期的帖子。
from django.db import models
import datetime
class Post(models.Model):
image = models.FileField(upload_to='images/')
title = models.CharField(default="", max_length=64)
description = models.CharField(default="", max_length=512)
date = models.DateField(default=datetime.date.today)
models.FileField(upload_to='images/')用作上传图像到我们在设置中配置的媒体目录中的图像文件夹的字段。
models.CharField(default="", max_length=n)是一个基本文本字段,最大字符长度为n。
models.DateField(default=datetime.date.today)顾名思义,这是一个日期/时间字段,设置为当前日期和时间。
为了完成我们的模型,让我们告诉 Django 按从新到旧的顺序排列它们:
class Post(models.Model):
image = models.FileField(upload_to='images/')
title = models.CharField(default="", max_length=64)
description = models.CharField(default="", max_length=512)
date = models.DateField(default=datetime.date.today)
class Meta:
ordering = ['-date']
def __str__(self):
return self.title
这个Meta类功能很多,在我们的例子中,我们将使用它来按时间顺序排列模型。该__str__函数告诉 Django,当我们稍后在 Django 管理面板中与条目交互时,显示标题(而不是显示“帖子 1”、“帖子 2”等)。[深入分析]
迁移我们的新模型
最后,使用以下两条命令完成我们的模型,这两条命令本质上是告诉 Django 我们做了一些更改,并且应该将这些更改应用到我们的数据库中:
python3 manage.py makemigrations
python3 manage.py migrate
恭喜!我们的数据库已经设置完毕,可以存放文章了。不过,现在还有一个问题:我们还无法编辑文章。接下来,我会帮您设置 Django 管理面板,以便您发布文章。
管理员控制面板
在我们的blog应用程序中,转到admin.py并添加以下内容:
from django.contrib import admin
from blog.models import Post
admin.site.register(Post)
from blog.models import Post导入我们刚刚创建的所有模型。admin.site.register(<model_name>)告诉 Django 在控制面板中显示该模型。
接下来,我们将创建一个超级用户,以便登录管理面板。输入以下命令并按照提示操作。您只需填写用户名和密码即可。
$ python3 manage.py createsuperuser
Username (leave blank to use 'ari'):
Email address:
Password:
Password (again):
Superuser created successfully.
完成后,请访问127.0.0.1:8000/admin并使用您刚才输入的凭据登录。您应该会看到以下页面:
在这里,您可以向 Django 项目添加文章。我们的模型部分已经全部完成。接下来,我们将设计视图,以便 Django 可以发布文章。
视图逻辑
视图是 Django 在我们请求页面时如何执行操作的方式。首先,我们需要在 ` views.py<path>` 目录下创建一个文件django_cc。将以下内容粘贴到该文件中:
from django.shortcuts import render
from django.views.generic.base import View
from django.views.generic import TemplateView
from blog.models import Post
class PostFeed(TemplateView):
template_name = 'index.html'
def get_context_data(self, *args, **kwargs):
context = dict()
context["posts"] = Post.objects.all()
return context
from django.views.generic import TemplateView它允许我们使用 Django 的基本模板视图,这足以满足我们展示文章的需求。from blog.models import Post它导入了视图函数所需的所有数据库模型。
PostFeed这是我们的基本模板视图,它将使用index.html我们接下来要创建的文件来渲染数据库内容。
get_context_data我们将通过这种方式将数据库中的信息发送到我们的模板。context["posts"] = Post.objects.all()我们的模板将引用字典posts中的context某个字段,以获取从数据库中收集的所有帖子列表。Post.objects.all()
我们urls.py需要添加一条新路径,以便 Django 知道何时请求该 URL 来调用我们的视图:
from django.conf.urls import url
from django.contrib import admin
from django.conf.urls.static import static
from django.conf import settings
# import path for easy urls
from django.urls import path
# import our views so urls.py can call them
from django_cc.views import PostFeed
urlpatterns = [
# Path for root of our website that will display the post feed
path('', PostFeed.as_view(template_name="index.html"), name="PostFeed"),
url(r'^admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
我们的基本视图逻辑已经完成,现在我们需要构建用于显示帖子的索引模板。
风格模板
在 Django 项目的根目录(包含 ` <project>`blog和 ` django_cc<link>` 文件夹)中,创建一个`<link>`templates文件夹,并在其中创建一个 ` <template> index.html` 文件。我们的网站设计将使用Bulma框架,因此无需编写任何 CSS。以下是一个可用于我们模板的样板代码。
<!DOCTYPE html>
<html lang="en">
<head>
<title>Posts | Django Crash Course</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css"
integrity="sha256-8B1OaG0zT7uYA572S2xOxWACq9NXYPQ+U5kHPV1bJN4="
crossorigin="anonymous"
/>
</head>
<body></body>
</html>
Django 模板使用一种名为 Django HTML 的 DRY(Don't Repeat Yourself,不要重复自己)版本的 HTML。我们将通过这种方式将上下文传递给模板进行渲染index.html。在模板主体中,我们添加一个包含文章上下文的基本卡片。
<div class="container">
{% for post in posts %}
<div class="card">
<div class="card-image">
<figure class="image">
<img
src="{{ post.image.url }}"
alt="Placeholder image"
style="max-width: 250px; max-height: 250px;"
/>
</figure>
</div>
<div class="card-content">
<div class="content">
<b>{{ post.title }}</b> | {{ post.description }}
<br />
<time datetime="{{ post.date }}">{{ post.date }}</time>
</div>
</div>
</div>
{% endfor %}
</div>
{% for post in posts %}充当 for 循环,将为循环内的每个帖子复制其内容posts。
每次 for 循环运行时,当前迭代中帖子的上下文都会被添加到 HTML 中,并在使用该上下文引用帖子时使用 `<div>` 标签。{{ <variable> }}
{{ post.image.url }}引用图片时,需要使用图片的 URL,不能直接引用图片本身。
当我们访问127.0.0.1:8000时,应该会看到控制面板中列出的所有我们添加的帖子:
现在我们有了一个网站,可以把我们添加到控制面板的内容以 Bulma 卡片的形式展示出来。真棒。
包起来
Django 是一个非常棒的框架,可以用来构建网站和其他复杂的项目。今天你已经创建了一个非常基础的网站,可以像 Instagram 一样展示帖子。希望将来你能自己搭建一个类似 Instagram 的网站。现在,我建议你通过 Django的官方文档或者这篇入门教程(我就是从这篇教程开始学习 Django 的)来深入了解它。
供您参考——请按照Digital Ocean 的教程学习如何托管您的 Django 项目,让全世界都能看到。如果您想使用 Digital Ocean 的托管服务,请使用我的推荐链接享受折扣。
文章封面照片由Fabian Grohs拍摄,来自Unsplash。
编辑:重命名了类以符合 PEP 8 规范,并将数据库应用程序重命名为博客。
编辑:已修复return context模板settings.py目录问题和博客模型引用问题。感谢 Chris Merck 的反馈。


