欢迎,来自IP地址为:18.97.14.87 的朋友



Django 是一款功能强大的 Python Web 框架,主要用于生成复杂的 Web 应用。Django 框架遵循模型-视图-模板(MVT)的架构,并内置了众多功能,例如认证、管理界面以及数据库管理等。

在本教程中,我们将逐步创建一个简单的 Web 应用,以获得使用 Django 核心功能的实践经验。在此过程中,我们将使用模型、视图、模板和管理界面来构建功能齐全的 Web 应用程序。这种实践过程将有助于我们揭开 Django 结构和功能的神秘面纱。

通过本教程的讲解,您将了解到:

  • Django 项目如何设置开发环境和创建项目结构
  • 简单的 HTML 和 CSS 知道有助于 Django 模板的设计,但这不是强制性的
  • Django 使用 Python 构建 Web 应用程序,提供内置功能和可扩展性
  • 如何使用 Django 创建一个展示项目和相关内容的实例网站

Django 简介

市面上有无数的 Web 开发框架,那么为什么要学习 Django 而不是其他框架呢?首先,它是用 Python 编写的,Python 是目前最易读且对初学者最友好的编程语言之一。

选择 Django 的第二个原因是其功能范围。在构建网站时,如果选择了 Django,则无需依赖任何外部库或软件包。这意味着我们不需要额外学习如何使用其他任何东西,而且语法是无缝的,因为全程只使用一个框架。

Django 还有一个额外的好处,就是更新起来非常简单,因为核心功能都包含在一个包中。如果确实需要添加额外的功能,可以使用多个外部库来实现。

Django 框架的另外一大优点就是其详尽的文档。它提供了有关 Django 各个方面的详细文档,还提供了出色的示例,甚至还有入门教程。

Django 还有一个很棒的开发者社区,因此如果我们在开发过速中遇到困难,几乎总能通过查看文档或向社区咨询找到解决方法。

Django 是一个具有大量功能的高级 Web 应用程序框架。由于其出色的文档,使它非常适合刚接触 Web 开发的人,如果熟悉 Python,那么它就尤其适合。

Django 网站的结构

Django 网站可以理解为一个项目,该项目分为多个单独的应用程序。其理念是每个应用程序处理网站需要执行的独立任务。例如,想象一下像 Instagram 这样的应用程序。它可能需要执行几个不同的任务:

  • 用户管理:登录、退出、注册等功能
  • 图片源:上传、编辑和显示图片功能
  • 私人消息:在用户之间发送消息并提供通知

这些不同的任务都是独立的功能,所以如果这个例子是一个 Django 网站,那么每个功能将是单个 Django 项目内的不同 Django 应用程序。

Django 项目包含一些适用于整个项目的配置,例如项目设置、URL、共享模板和静态文件。每个应用程序都可以拥有自己的数据库,并且有自己的函数来控制如何在 HTML 模板中向用户显示数据。

每个应用程序还有自己的 URL 以及自己的 HTML 模板和静态文件,例如 JavaScript 和 CSS。

Django 应用程序的结构使得逻辑分离。它支持模型-视图-控制器模式(MVC),这是大多数 Web 框架的架构。基本原则就是每个应用程序包含三个单独的文件,分别处理三个主要逻辑部分:

  • 模型定义数据结构,这通常是数据库描述,是应用程序的基础层
  • 视图使用 HTML 和 CSS 向用户显示部分或全部数据
  • 控制器处理数据库和视图如何交互

如果想了解有关 MVC 模式的更多信息,请查看相关资料。

在 Django 中,架构略有不同。尽管它基于 MVC 模式,但 Django 自己处理控制器部分。无需定义数据库和视图如何交互。一切都由 Django 做好了!

Django 使用的模式称为模型-视图-模板 (MVT) 模式。开发人员需要做的就是添加视图映射到的一些 URL 配置,其余部分由 Django 处理!

Django 网站以项目开始,我们可以使用多个应用程序构建它,每个应用程序处理单独的功能。每个应用程序都遵循模型-视图-模板模式。

现在我们已经熟悉了 Django 网站的结构,下面就看看我们要构建什么。

创建 Django 示例项目

在开始任何 Web 开发项目之前,最好先制定一个计划,确定要构建的内容。在本教程中,您将使用以下应用程序通过示例构建一个 Django 项目:

  • 页面:这个 Django 应用将用于向网站访问都显示一些初步内容。这是一个很好的起点,我们并且可以稍后对其进行增强以满足自己的需求
  • 项目:我们可以在这里展示以前的 Web 开发项目。示例将构建一个画廊风格的页面,其中包含指向我们已完成的项目的可点击链接

Django 的最大优点就是,我们无需考虑外部 Python 包,因为 Django 包含许多功能。但是,我们同样需要包含 Bootstrap 来帮助我们设计模板。

通过构建以上两个应用程序,我们将学习 Django 模型、视图函数、模板和 Django 管理站点的基础知识。了解这些功能后,我们将能够构建更多应用程序。同时,我们还将学习更多知识来构建复杂 Django 项目以及相关工具。

搭建开发环境

每当开始一个新的 Web 开发项目时,最好先设置其开发环境。为我们的项目创建一个新目录,然后进入该目录:

# mkdir -p webApp
# cd webApp

进入项目目录后,最好创建一个虚拟环境来管理依赖项。根据主机的操作系统,然后使用特定于平台的命令来设置 Python 虚拟环境:

PS> python -m venv venv
# python -m venv venv

此命令将会在项目工作目录中创建一个”venv”文件夹。在此目录中,我们可以找到几个文件,包括 Python 标准库的副本。之后,当我们再安装新的依赖项时,它们也将位于此目录中。接下来,我们需要通过运行以下命令来激活虚拟环境:

PS> .\venv\Scripts\activate
(venv) PS>
# source venv/bin/activate
(venv) #

使用上述命令,就可以创建并激活名为 venv 的虚拟环境。提示符前面的括号”(venv)”表示我们已成功激活了虚拟环境。

现在我们已经创建并激活了虚拟环境,是时候安装 Django 了。可以使用 pip 执行此操作:

(venv)# python -m pip install Django

之后,就需要等待 Django 安装成功。设置虚拟环境并安装 Django 后,我们就可以开始创建应用程序了。

启动 Django 项目

正如之前提到的,Django Web 应用程序由项目及其应用程序组成。确保位于”webApp”目录中,并且已激活虚拟环境。然后运行以下命令来创建项目:

(venv) # django-admin startproject webApp .

不要忘记上面命令末尾添加点”.”号。这个点可防止 Django 将我们的项目创建到其他嵌套目录中。否则,我们最终会得到一个包含 webApp/ 子目录的 webApp/ 文件夹。

通过运行如上所示的 startproject 命令,我们已告诉 Django 在 webApp/ 目录中创建一个 webApp/ 文件夹。Web 应用的目录结构应如下所示:

webApp/
│
├── webApp/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
│
└── manage.py

设置好文件结构后,现在就可以启动 Django 开发服务器并检查设置是否成功。在控制台中,运行以下命令:

(venv) # python manage.py runserver

然后,在浏览器中访问 http://localhost:8000,就可以看到以下内容:

是时候庆祝一下了,我们已经创建了一个 Django 网站!下一步是创建应用程序,以便可以向网站添加视图和功能。

添加页面应用(Pages)

在本教程的这一部分,我们将创建一个名为 pages 的应用程序,它将包含 web 应用网站的基本欢迎页面。

要创建该应用程序,则运行如下命令:

(venv) # python manage.py startapp pages

命令执行完成后,将会在当前目录创建一个包含多个文件的 pages/ 目录,文件清单如下:

  • __init__.py:告诉 Python 将目录视为 Python 包
  • admin.py:包含 Django 管理页面的设置
  • apps.py:包含应用程序配置的设置
  • models.py:包含一系列 Django 的 ORM 转换为数据库表的类
  • tests.py:包含测试类
  • views.py:包含处理 HTML 模板中显示的数据的函数和类

创建完 pages 应用程序后,我们需要将其安装到项目中。在 webApp/webApp/settings.py 中的 INSTALLED_APPS 下添加以下代码行:

# ...

INSTALLED_APPS = [
    "pages.apps.PagesConfig",
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
]

# ...

要将应用包含在 Django 示例项目中,我们需要在 settings.py 中的 INSTALLED_APPS 列表开头添加对其配置类的引用。

通过添加 pages.apps.PagesConfig,就可以让 Django 知道我们刚刚创建的 pages 应用存在。下一步是创建一个视图,以便可以向访问者显示一些内容。

创建显示视图

Django 中的视图是应用目录中 views.py 文件中的函数或类的集合。每个函数或类处理应用每次用户访问不同 URL 时处理的逻辑。

导航到 pages/ 目录中的 views.py 文件并添加以下代码:

from django.shortcuts import render

# Create your views here.

def home(request):
    return render(request, "pages/home.html", {})

在这段代码中,我们定义了一个名为 home() 的视图函数。当我们调用此函数时,它将呈现一个名为 home.html 的 HTML 文件。虽然该文件尚不存在,但我们很快就会创建它。

注意:视图函数至少需要一个参数 request。请求对象在页面加载时创建,其中包含有关页面请求的元数据。可以在 Django 文档的请求和响应对象中了解有关请求对象的更多信息。

现在我们已经创建了视图函数,还需要创建要显示给用户的 HTML 模板。render() 函数在应用目录中名为 templates/ 的目录中查找 HTML 模板。由于不同应用的模板可以具有相同的名称,因此最佳做法是在 templates/ 目录中添加一个与应用同名的子目录:

(venv) # mkdir -p pages/templates/pages
(venv) # touch pages/templates/pages/home.html

创建模板文件夹和 home.html 后,在编辑器中打开 HTML 文件并添加以下代码行:

<h1>Hello, World!

现在我们已经创建了 home() 视图函数所需的模板,同时还需要告诉 Django 何时提供视图。为此,我们需要创建一条通往项目的访问路由。

添加路由

接下来,我们需要连接一个 URL,以便访问刚刚创建的页面。在 webApp/ 文件夹包含一个名为 urls.py 的文件。在此文件中,我们将包含页面添加到应用程序的 URL 配置:

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    path("", include("pages.urls")),
]

通过向 urlpatterns 添加另一个 path(),就可以为 Django 示例项目创建新的路由。每当用户访问项目的根路径时,pages 应用程序的路由都会加载。pages.urls 模块尚不存在,因此需要创建它:

(venv) # touch pages/urls.py

在 urls.py 中,需要导入路径对象以及应用程序的视图模块。然后定义与各种视图函数相对应的 URL 模式列表。目前,我们只创建了一个视图函数,因此只需包含一个路由:

from django.urls import path
from pages import views

urlpatterns = [
    path("", views.home, name="home"),
]

现在,我们就可以查看个性后的主页了。如果 Django 开发服务器不再运行,则使用以下命令重新启动它:

(venv) # python manage.py runserver

然后,访问 http://localhost:8000 ,以查看我们创建的 HTML 模板是否生效:

恭喜!现在我们已经创建了第一个 Django 应用并将其连接到项目中。现在唯一的问题是它看起来不太好看。在之后的内容中,我们将为项目添加一些样式,使其更漂亮!

如果开发服务器启动不成功,报错提示”NameError: name ‘include’ is not defined”,这是因为我们在添加路由时使用了”include()”函数而未对其进行引用,需要在 webApp/urls.py 开头添加如下代码引入 include 函数:

from django.conf.urls import include

添加 Bootstrap 应用

如果不添加任何样式,那么我们创建的应用程序看起来就不会太好看。本教程不介绍 CSS 样式表,而是介绍如何将外部 CSS 框架添加到项目中。使用 CSS 框架可以让我们轻松修改网站的外观。

目前最为流行的 CSS 框架就是 Bootstrap

Bootstrap 是一个免费的开源 CSS 框架,旨在实现响应式、移动优先的前端 Web 开发。它包含 HTML、CSS 和(可选)基于 JavaScript 的设计模板,用于排版、表单、按钮、导航和其他界面组件。

一旦添加到项目中,Bootstrap 就会为所有 HTML 元素提供基本样式定义。结果是文章、表格和表单元素在各个 Web 浏览器中具有统一的外观。此外,开发人员可以利用 Bootstrap 中定义的 CSS 类来进一步自定义其内容的外观。

在开始使用 Bootstrap 样式之前,我们将创建一个可以导入到每个后续视图的基本模板。此模板是随后添加 Bootstrap 样式导入的地方。

在 webApp/ 文件夹中创建一个名为 templates/ 的目录。在这个新目录中,创建一个名为 base.html 的文件:

(venv) # mkdir templates/
(venv) # touch templates/base.html

正如之前所描述的那样,每个 Django 项目可以由多个处理单独逻辑的应用程序组成,并且每个应用程序都包含自己的 templates/ 目录来存储与应用程序相关的 HTML 模板。而对于整个项目共享的模板,最好在根目录中创建一个 templates/ 目录。

这样,我们就不必将 Bootstrap 样式导入每个应用程序,而是可以创建一个或一组所有应用程序共享的模板。只要 Django 知道在这个新的共享目录中查找模板,它就可以节省大量重复的样式。

在 base.html 中,添加如下代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>{% block title %}My webApp{% endblock title %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" >
</head>
<body class="container">
{% block page_content %}{% endblock page_content %}
</body>
</html>

使用上面的代码,我们就创建了一个 HTML 文档框架模板。模板中还通过”link”标签引入了 Bootstrap 框架。我们之后创建的所有页面都可能通过扩展 base.html 并在每个页面上继承 Bootstrap 样式,而无需再次导入样式。

base.html 作为所有模板的父模板,就是使用了模板标签 {% block %} 。使用此模板标签,我们就可以定义可在父模板的子模板中使用或覆盖的内容块。

要查看此继承的实际效果,我们可以调整 home.html 模板为如下内容:

{% extends "base.html" %}

{% block page_content %}
<h1>Hello, World!</h1>
{% endblock page_content %}

要扩展使用父模板,必须在子模板的开头使用 {% extends %} 标记。

请注意,我们只能覆盖 page_content 块,而不能覆盖标题块。如果不覆盖父模板的块,则会在子模板中显示父模板块的内容。

在看到继承和新样式应用程序的实际效果之前,我们需要告诉 Django 示例项目 base.html 存在。默认设置在每个应用程序中注册模板/目录,但不在根目录本身中注册。在 webApp/settings.py 中,更新 TEMPLATES:

# ...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            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',
            ],
        },
    },
]
# ...

我们已经在 settings.py 中定义了常量 BASE_DIR,它指向项目的根目录。接下来,将 pathlib 中的路径与正斜杠运算符 (/) 连接起来,以指向 templates/ 目录并将其添加到”DIRS”列表中。

现在,再次访问 localhost:8000 时,我们将可以看到页面的格式略有不同。这得益于 Bootstrap,即使在不同的浏览器中加载页面,样式看起来也应该相似。

在这个页面中,既有在 home.html 中定义的 Hello, World! 消息,也有 base.html 中设置的 My webApp 标题。这意味着模板继承有效!

每当我们想要创建模板或导入要在项目内的所有 Django 应用中使用的脚本时,都可以将它们添加到此项目级目录并在应用模板中扩展它们。

之后,我们将新增一个 Projects 应用,以显示更多有意义的内容。

添加 Projects 应用

假设我们现在想要创建一个新的应用,用于展示我们曾经的辉煌项目经历。于是我们需要创建另一个名为 Projects 的 Django 应用,它将包含一系列我们想要向用户显示的示例项目。用户可以单击项目并查看更多信息。

确保位于 webApp/ 目录中,并在控制台中运行以下命令:

(venv) # python manage.py startapp projects

这将会创建一个名为 projects/ 的目录。创建的文件与启动 pages 应用时创建的文件相同。

创建 projects 应用程序后,我们同样需要将其安装到项目中。在 webApp/webApp/settings.py 文件中的 INSTALLED_APPS 下添加以下代码引入 projects 应用:

# ...

INSTALLED_APPS = [
    'pages.apps.PagesConfig',
    'projects.apps.ProjectsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

# ...

标红这行代码意味着我们的项目现在知道 projects 应用程序存在。接下来,我们将修改 projects 应用程序并构建我们第一个 Django 模型。

定义模型

如果我们想要存储数据以在网站上显示,那么就需要一个数据库。通常,如果我们想要创建一个包含行和列数据表的数据库,则需要使用 SQL 来管理数据库。但是当使用 Django 时,则不需要学习 SQL 语句,因为它具有内置的对象关系映射器 (ORM)。

ORM 是一个允许我们创建与数据库表相对应的类的程序。类属性对应于列,类的实例对应于数据库中的行。因此,我们就无需学习 SQL 来创建数据库及其表,只需编写一些 Python 类即可。

当我们使用 ORM 时,代表数据库表的类称为模型。在 Django 中,它们位于每个 Django 应用程序的 models.py 模块中。

在我们的项目应用程序中,只需要一个表来存储要向用户显示的不同内容。这意味着我们只需要在 models.py 中创建一个模型。

我们将创建的模型将被命名为 Project,并将具有以下字段:

字段名 字段描述
title 一个短字符串字段,用于保存项目名称
description 更长的字符串字段,可容纳更多的文本来描述项目信息
technology 字符串字段,但其内容将限制为选定数量的选项

要创建 Project 模型,我们需要在 models.py 中创建一个新类并添加相应字段:

from django.db import models

class Project(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    technology = models.CharField(max_length=20)

Django 模型带有许多内置模型字段类型。我们在此模型中仅使用了两种。其中 CharField,它适用于短字符串并可以指定最大长度;TextField 类似于 CharField,但可以将其用于较长的文本,因为它没有最大长度限制。

现在我们已经创建了 Project 类,还需要 Django 来创建数据库。默认情况下,Django ORM 在 SQLite 中创建数据库,当然也可以使用支持 SQL 语句的其他类型数据库(如 PostgreSQL 或 MySQL)与 Django ORM 一起使用。使用的数据库的类型,在 webApp/settings.py 文件中,由 DATABASES 指定。

要开始创建数据库的过程,我们需要创建迁移。迁移是一个包含 Migration 类的文件,该类具有告诉 Django 需要对数据库进行哪些更改的规则。要创建迁移,确保位于 webApp/ 目录中,在控制台中键入以下命令:

(venv) # python manage.py makemigrations projects

可以看到,我们已经在 projects/ 中创建了 migrations/,它包含一个名为 0001_initial.py 的文件。此文件包含 Django 应在数据库上执行的指令。

我们已经创建了迁移文件,就需要在迁移文件中应用迁移并使用迁移命令创建数据库:

(venv) #python manage.py migrate projects

在运行 makemigrations 和 migration 命令时,我们会将 projects 添加到命令中。这告诉 Django 仅查看 projects 应用程序中的模型和迁移。

如果在没有项目标志的情况下运行 makemigrations 和 migration,则将创建并应用 Django 项目中所有默认模型的所有迁移,因为 Django 已经附带了多个模型。这不是问题,但对于示例而言,我们不需要这些模型的迁移。

运行迁移后, 在 webApp/ 中现在有一个名为 db.sqlite3 的文件。这是我们的后台数据库。之后,我们就可以在表中为示例网站上显示的各项内容创建对应的行。

深入使用 Django shell 命令行

要向 Project 数据库表添加新条目,我们需要创建 Project 类的实例。为此,将使用 Django shell。

Django shell 类似于 Python shell,但允许访问数据库并创建条目。要访问 Django shell,需要使用另一个 Django 管理命令:

(venv) # python manage.py shell

进入 shell 后,命令提示符会变为三个插入符号 (>>>),这就与 Python 十分类似了。然后,我们就可以导入项目模型:

>>> from projects.models import Project

然后,您可以在 Django shell 中创建 Project 类的实例:

>>> first_project = Project(
...     title="My First Project",
...     description="A web development project.",
...     technology="Django",
... )
>>> first_project.save()

我们首先将 first_project 创建为新的 Project 类实例,并用 save() 方法将实例映射保存到数据库。完成操作后,会在数据库 projects 表中创建一条记录并将其保存到数据库。于是,我们已经添加一条项目信息,稍后就可以在应用网站上显示该项目信息。

依类似操作,继续在数据库中添加另外两个项目:

>>> second_project = Project(
...     title="My Second Project",
...     description="Another web development project.",
...     technology="Flask",
... )
>>> second_project.save()
>>> third_project = Project(
...     title="My Third Project",
...     description="A final development project.",
...     technology="Django",
... )
>>> third_project.save()
>>> exit()

全部项目信息添加完成后,运行 exit() 退出 Django shell。

接下来,我们将获取添加到数据库的项目并创建一个视图函数以在网页上向用户显示它们。

创建视图

现在,我们已经创建了项目,接着还需要创建视图函数,并将数据库中的数据发送到模板,以便在应用程序网站上显示它们。

在 projects  应用中,我们将创建两个不同的视图:

  • 索引视图:用于显示有关每个项目的简洁信息
  • 详细视图:用于显示有关特定内容的更多信息

我们将把这两个视图添加到 Django 已经创建好的 views.py 文件中。在 views.py 中,我们需要从 models.py 导入 Project 类,并创建一个 project_index() 函数,该函数呈现名为 project_index.html 的模板。在此函数的主体中,我们将进行 Django ORM 查询以选择 projects 表中的所有对象:

from django.shortcuts import render

# Create your views here.
from projects.models import Project

def project_index(request):
    projects = Project.objects.all()
    context = {
        "projects": projects
    }
    return render(request, "projects/project_index.html", context)

以上代码块中有较多内容,可以将其分解进行说明。

首先引入 Project 类,然后定义一个 project_index() 函数,用于接收请求并返回结果。

之后使用 Project 对象的 all() 方法执行查询,用以查询出数据表中的所有数据集。数据库查询返回与查询匹配的所有对象的集合,称为查询集。在本例中,我们需要表中的所有对象,因此它将返回之前创建的三个项目信息的集合。

为了显示查询结果,我们定义了一个名为 context 的字典。该字典只有一个条目,即 projects,它将包含所有 projects 的查询集分配给该条目。Django 使用上下文字典将信息发送到我们创建的模板中。

最后,我们将 context 作为参数添加到 render()。只要将 context 参数传递给 render(),上下文字典中的任何条目都可以在模板中使用。

注意:我们还将名为 project_index.html 的模板的路径添加到 render() 中。虽然此模板尚不存在,但不要担心,我们之后会创建该模板。

接下来,我们继续创建 project_detail() 视图函数。此函数会将正在查看的项目的主键作为附加参数:

def project_detail(request, pk):
    project = Project.objects.get(pk=pk)
    context = {
        "project": project
    }
    return render(request, "projects/project_detail.html", context)

在详情信息页面,我们使用 get() 方法执行了另一个查询。此查询使用主键 pk(等于函数的参数)检索项目。主键是数据库条目的唯一标识符。

我们可以使用 Django shell,单步执行 views.py 中的查询语句,以验证视图的查询集是否包含预期的对象。在 project_detail() 中,我们定义上下文,并将请求的项目信息添加到其中。

最后,我们同样将内容传入一个名为 project_detail.html 的尚不存的模板。这个模板也同样需要后续创建。

制作模板

根据之前的需求,现在创建已经在视图中使用的两个模板,分别名为 project_index.html 和 project_detail.html。在 projects 应用程序的 templates/ 文件夹中的 projects/ 子文件夹中创建它们:

(venv) # mkdir -p projects/templates/projects
(venv) # touch projects/templates/projects/project_index.html
(venv) # touch projects/templates/projects/project_detail.html

对于 project_index.html 模板,我们将创建一个 Bootstrap 卡片网格,每个卡片显示项目的详细信息。当然,要显示的项目数量会因查询结果的不同而发生变化。

为了避免手动创建一堆 Bootstrap 卡片并将所有信息手动编码到每个项目中,我们将使用 Django 模板引擎的一项功能:for 循环。

借助此功能,我们将能够循环遍历所有项目信息并为每个项目创建一张卡片。Django 模板引擎中的 for 循环语法如下:

{% for project in projects %}
   
{% endfor %}

其中 projects 是我们通过 render()方法传递给模板的结果集,而 project 则是结果集中的每一个结果项,这个结果项包含了每条记录的详细信息,包括名称、描述以及使用技术等内容。这个结果项就可以在模板文件 for 语句块中使用。

了解了 for 循环的工作原理,就可以修改 projects/templates/projects 目录中的 project_index.html 文件。具体代码如下:

{% extends "base.html" %}

{% block page_content %}
<h1>Projects</h1>
<div class="row">
    {% for project in projects %}
    <div class="col-md-4">
        <div class="card mb-2">
            <div class="card-body">
                <h5 class="card-title">{{ project.title }}</h5>
                <p class="card-text">{{ project.description }}</p>
                <a href="{% url 'project_detail' project.pk %}"
                   class="btn btn-primary">
                    Read More
                </a>
            </div>
        </div>
    </div>
    {% endfor %}
</div>
{% endblock %}

这里有很多 Bootstrap HTML代码,但这不是本教程的重点。我们可以随意使用它,如果有兴趣了解更多信息,请查看 Bootstrap 文档。

与在 pages 应用程序中一样,我们首先扩展了 base.html。

然后使用 for 循环,循环遍历上下文字典传入的所有项目数据。在这个 for 循环中,我们可以访问每个单独的项目。要使用项目的属性,我们可以在双花括号内使用点符号。例如,要访问项目的标题,则使用 {{ project.title }}。

最后要注意的一点是创建的链接。这是指向 project_detail 页面的链接。在 Django 中访问 URL 类似于访问静态文件。 URL 的代码形式如下:

{% url '<url path name>' <view_function_arguments> %}

在这种情况下,我们创建了一个名为 project_detail 的 URL 路径,并且使用与项目的 pk 号相对应的参数。

有了 project_index.html 模板,现在该创建 project_detail.html 模板了。此模板的代码如下:

{% block page_content %}
<h1>{{ project.title }}</h1>
<div class="row">
    <div class="col-md-4">
        <h5>About the project:</h5>
        <p>{{ project.description }}</p>
        <br>
        <h5>Technology used:</h5>
        <p>{{ project.technology }}</p>
    </div>
</div>
{% endblock page_content %}

此模板中的代码具有与 project_index.html 模板中的每个项目卡相同的功能。唯一的区别是引入了一些 Bootstrap 列。

现在视图和模板已经存在,是时候添加相应的路由了,这样我们就可以看到刚刚创建的模板的运行效果了。

添加路由

定义好视图函数后,我们需要将它们连接到 URL。首先创建一个 projects/urls.py 文件来保存 projects 应用程序的 URL 配置。此文件包含以下代码:

from django.urls import path
from projects import views
    urlpatterns = [
    path("", views.project_index, name="project_index"),
    path("<int:pk>/", views.project_detail, name="project_detail"),
]

在导入需要的引用后,首先将 projects 应用程序的根 URL 连接到 project_index 视图。连接 project_detail 视图稍微复杂一些。我们希望 URL 为 /1、/2 等与项目主键相对应的数字。URL 中的 pk 值与传递给视图函数的 pk 相同,因此需要根据要查看的项目动态生成这些 URL。为此,我闪使用了 <int:pk> 表示法。

此表示法告诉 Django,URL 中传递的值是一个整数,其变量名称是 pk。这是 project_detail() 视图函数的参数。

设置好 projects 应用程序的路由后,就需要将这些 URL 连接到主 Django 项目的 URL。在 webApp/urls.py 中,添加以下标红显示的代码行:

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("pages.urls")),
    path("projects/", include("projects.urls")),
]

这行代码包含 projects 应用程序中所有包含前缀 projects/ 的 URL。现在有两个完整的 URL 可供我们的项目访问。

启动 Django 服务器并访问 http://localhost:8000/projects,则应该会看到类似以下内容:

如果单击项目链接或直接访问 http://localhost:8000/projects/1,那么将看第一个项目的详细信息页面。

查看列出的项目并访问其详细信息页面,全过程实现后就显得很酷。但是,没有图片显示似乎有点乏味。之后,我们将做一些改进,以方便地更新项目并为添加图片做好准备。

利用 Django 管理站点

您可能已经注意到,在运行 Django 开发服务器时,Django 提醒您有一些未应用的迁移。

现在是时候最终应用这些已经存在的迁移了:

(venv) # python manage.py migrate

查看已应用迁移的列表可以让我们了解 Django 已包含的功能。例如,现在,我们已经拥有用户认证和 Django 管理站点功能。

要访问 Django 管理站点,必须先为自己创建一个管理员帐户:

(venv) # python manage.py createsuperuser

运行 createsuperuser 管理命令将提示您选择用户名、提供电子邮件地址并设置密码。全部设置完成后,就完成了管理员用户的添加。

再次启动 Django 开发服务器,访问 http://localhost:8000/admin,然后使用之前创建用户凭据登录,就会进入 Django 的管理页面:

这是我们自己的管理区域,只需进行一些调整,就可以轻松地从浏览器窗口而不是 Django shell 管理我们的网站应用项目。

要在 Django 管理站点中访问 projects 模型,需要先注册该模型。打开 projects 应用程序的 admin.py 文件并添加以下代码:

from django.contrib import admin

# Register your models here.
from projects.models import Project

class ProjectAdmin(admin.ModelAdmin):
    pass

admin.site.register(Project, ProjectAdmin)

再次访问 http://localhost:8000/admin 时,我们会发现 projects 项目会显示在管理网站上。

上传图片文件

使用图片是吸引访客的注意力是一个好主意。为此,我们可以将向 Project 模型添加一个新字段,并在 Django 管理站点中上传图片。

首先打开 projects 应用的 models.py 文件,并向其中添加一个图像字段:

class Project(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    technology = models.CharField(max_length=20)
    image = models.FileField(upload_to="project_images/", blank=True)

在 Project 模型中,我们定义了一个新的字段image,使用 FileField 类型,其中包含一个名为 project_images/ 的子​​文件夹。这就是上传图片时 Django 存储图片的地方。

我们还将 blank 设置为 True,表示该字段可以为空,也就是不上传项目图片也没关系。

注意:我们也可以更明确地使用 ImageField 来存储图像。如果这样做,则需要先将 Pillow 安装到开发环境中。

Django 使用 MEDIA_ROOT 设置和 upload_to 值共同构建上传文件夹的路径。要收集 uploads/ 文件夹中的所有图像并使用 media/ URL 提供给它们,则将以下两行添加到 settings.py:

MEDIA_ROOT = BASE_DIR / "uploads/"
MEDIA_URL = "media/"

MEDIA_ROOT 设置了文件系统中存储媒体文件的文件夹。MEDIA_URL 是向访问者展示的媒体文件夹的面向用户的 URL。

要成功提供媒体文件,我们还需要在 webApp/ 内的 urls.py 中注册到媒体文件的静态路由:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
                  path("admin/", admin.site.urls),
                  path("", include("pages.urls")),
                  path("projects/", include("projects.urls")),
              ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

由于我们对 Django Project 模型做了一些更改,因此必须创建一个新的迁移,然后迁移这些更改:

(venv) # python manage.py makemigrations projects
(venv) # python manage.py migrate projects

访问 http://localhost:8000/admin 并转到 projects 。单击进入某个 project,就会看到新的图像字段和选择文件的选项:

现在,就可以为每个具体项目上传图片了。

所有项目都包含图片后,我们就可以修改模板文件,让图片可以显示出来。从 project_index.html 开始:

{% extends "base.html" %}

{% block page_content %}
<h1>Projects</h1>
<div class="row">
    {% for project in projects %}
    <div class="col-md-4">
        <div class="card mb-2">
            {% if project.image %}
            <img class="card-img-top" src="{{ project.image.url }}">
            {% endif %}
            <div class="card-body">
                <h5 class="card-title">{{ project.title }}</h5>
                <p class="card-text">{{ project.description }}</p>
                <a href="{% url 'project_detail' project.pk %}"
                   class="btn btn-primary">
                    Read More
                </a>
            </div>
        </div>
    </div>
    {% endfor %}
</div>
{% endblock %}

标红部分的代码会检查项目是否包含图像,如果项目图像存在,则加载图像 URL 并显示该图像。转到 http://localhost:8000/projects/,查看最终效果:

最后,同样可以将图像添加到 project_detail.html 模板中,并且将图像标签包装在 if 条件中:

{% block page_content %}
<h1>{{ project.title }}</h1>
<div class="row">
    <div class="col-md-8">
        {% if project.image %}
        <img src="{{ project.image.url }}" width="100%">
        {% endif %}
    </div>
    <div class="col-md-4">
        <h5>About the project:</h5>
        <p>{{ project.description }}</p>
        <br>
        <h5>Technology used:</h5>
        <p>{{ project.technology }}</p>
    </div>
</div>
{% endblock page_content %}

借助 HTML 元素和 Bootstrap 类,我们可以将图像放置在项目信息的左侧。访问项目的详细信息页面时,就可以看到布局的实际效果。例如,查看 http://localhost:8000/projects/1/:

将图片包含到 projects 应用程序中是本教程的最后一步,至此,我们已经涉及了很多内容,但朋友们也可以继续练习和构建。构建的越多,它就会变得越直观,同时参考本教程的次数也就越少。希望各位朋友在 Django 学习上取得成功。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注