django框架学习

django入门

由于Django是在快节奏的新闻编辑室环境中开发的,所以它的设计目的是使常见的web开发任务变得快速和简单。下面是如何使用Django编写数据库驱动的Web应用程序的非正式概述。

为什么选择Django?

第一个原因是因为它是用python写的,对于新人来说可读性很高,而且友好。
第二个原因去学习Django是因为它广泛的特性。如果你需要去建立一个网站,你不需要学习其他额外的东西。

并且,它的文档充分/足够。
有一个咨询的社区。
是一个高等级的网络应用框架有很多特性。

Django网站的结构

Django网站由一个单独的项目组成,该项目被分割成不同的应用程序。其理念是,每个应用程序都处理站点需要执行的自包含功能。举个例子,想象一下Instagram这样的应用程序。有几个不同的功能需要执行:

  • 用户管理:登录、注销、注册等等
  • 图像提要:上传、编辑和显示图像
  • 私有消息:用户和通知之间的私有消息

这些都是单独的功能块,所以如果这是Django站点,那么每个功能块都应该是单个Django项目中的不同Django应用程序。

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

使用了MVC结构。

在Django中,架构略有不同。虽然Django基于MVC模式,但它自己处理控制器部分。不需要定义数据库和视图如何交互。都是为了你!

Django使用的模式称为Model-View-Tempalate (MVT)模式。

做一个应用程序

在开始任何web开发项目之前,最好先对将要构建的内容制定一个计划。在本教程中,我们将构建一个具有以下功能的应用程序:

  • 一个功能齐全的博客:如果你想展示你的编程能力,博客是一个很好的方式。在这个应用程序中,您将能够创建、更新和删除博客文章。文章将有可以用来分类的类别。最后,用户可以在帖子上留下评论。

  • 您的工作组合:您可以在这里展示以前的web开发项目。您将构建一个画廊样式页面,其中包含指向已完成项目的可单击链接。

Hello,World程序

现在您已经了解了Django应用程序的结构,以及将要构建的内容,接下来我们将介绍如何在Django中创建应用程序。稍后,您将把它扩展到您的个人投资组合应用程序中

创建一个你的开发环境

无论你开发一个什么样的web开发项目,最好就是一开始先去配个。创建一个目录然后进入

$ mkdir rp-portfolio
$ cd rp-portfolio

使用enev去创建一个虚拟环境。

$ python3 -m venv venv

此命令将在工作目录中创建一个文件夹venv。在这个目录中,您将发现几个文件,包括Python标准库的副本。稍后,当您安装新的依赖项时,它们也将存储在这个目录中。接下来,您需要运行以下命令来激活虚拟环境:

$ source venv/bin/activate

注意:如果你不是在用一个bash shell,你可能需要去使用一个不同的命令去激活你的虚拟环境。举个例子,就像在windows上,你会用这个命令

C:\> venv\Scripts\activate.bat

您将知道您的虚拟环境已被激活,因为终端中的控制台提示符将发生更改。它应该是这样的:

(venv) $

注意:你的虚拟环境目录不需要被称为venv。如果你想要去创建一个在一个不同的名字下,就像my_venv,用my_venv替换第二个venv。

然后,在激活虚拟环境时,再次使用my_venv替换venv。提示符现在也将以(my_venv)作为前缀。

既然已经创建了一个虚拟环境,现在就可以安装Django了。您可以使用pip来实现这一点:

(venv) $ pip install Django

设置好虚拟环境并安装Django之后,现在就可以开始创建应用程序了。

创建一个Django项目

Django web应用程序由一个项目及其组成的应用程序组成。确保您在rp_portfolio目录中,并且您已经激活了您的虚拟环境,运行以下命令来创建项目:

$ django-admin startproject personal_portfolio

这将创建一个新的目录personal_portfolio。如果您将cd放入这个新目录,您将看到另一个名为personal_portfolio的目录和一个名为manage.py的文件。你的目录结构应该是这样的:

rp-portfolio/
│
├── personal_portfolio/
│   ├── personal_portfolio/
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   │
│   └── manage.py
│
└── venv/

您所做的大部分工作将在第一个personal_portfolio目录中。为了节省每次处理项目时都必须通过多个目录进行cd处理的时间,将所有文件向上移动到一个目录,**稍微重新排序可能会有所帮助。**在rp-portfolio目录中,运行以下命令:

$ mv personal_portfolio/manage.py ./
$ mv personal_portfolio/personal_portfolio/* personal_portfolio
$ rm -r personal_portfolio/personal_portfolio/

然后最后这样:

rp-portfolio/
│
├── personal_portfolio/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
├── venv/
│
└── manage.py

一旦你的文件结构构建了,你能够检测服务器开始然后检测你的开始是否成功。在控制台,运行

$ python manage.py runserver

然后,在浏览器中转到localhost:8000,您应该会看到以下内容:
在这里插入图片描述
本教程这一部分的源代码可以在GitHub上找到。下一步是创建应用程序,以便向站点添加视图和功能。

创建一个Django 应用

对于这部分的教程,我们会创建一个app叫做 hello_world, 你之后会删掉它因为它对于我们的公文包网站来说没有用。
使用下面的命令,去创建一个app:

$ python manage.py startapp hello_world

这将创建另一个名为hello_world的目录,其中包含几个文件:

  • init.py告诉Python将该目录视为一个Python包。
    (直接从init开始运行)
  • admin.py包含Django管理页面的设置。
  • apps.py包含应用程序配置的设置。
  • models.py包含一系列类,Django的ORM将这些类转换为数据库表
  • tests.py包含测试类
  • views.py包含处理HTML模板中显示的数据的函数和类。

一旦创建了应用程序,就需要将其安装到项目中。在rp-portfolio /设置。,在INSTALLED_APPS下添加以下代码行:

添加已经安装的apps

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello_world', #hello_world
]

这行代码意味着您的项目现在知道您刚刚创建的应用程序已经存在。下一步是创建一个视图,以便向用户显示一些内容。

创建一个视图

视图在Django是一系列的函数和类在views.py 文件中,在你app目录下。每个函数或类处理每次访问不同URL时处理的逻辑。

导航到hello_world目录中的views.py文件。其中已经有一行代码导入了render()。添加以下代码:

from django.shortcuts import render

def hello_world(request):
    return render(request, 'hello_world.html', {})

在这一块代码中,你已经定义了一个视图函数叫做hello_world()。当调回用这个函数的时候,它发送一个HTML文件叫做hello_world.html。这个文件还没有存在,然后我们很快会创建它。

view函数接受一个参数request。此对象是HttpRequestObject,它在加载页面时创建。它包含关于请求的信息,例如方法,该方法可以取几个值,包括GET和POST。

既然已经创建了视图函数,就需要创建HTML模板来显示给用户。render()在应用程序目录中名为templates的目录中查找HTML模板。创建该目录,然后在其中创建一个名为hello_world.html的文件:

$ mkdir hello_world/templates/
$ touch hello_world/templates/hello_world.html

添加以下HTML行到您的文件:

<h1>Hello, World!</h1>

现在,您已经创建了一个函数来处理要显示给用户的视图和模板。最后一步是连接url,这样您就可以访问刚刚创建的页面。您的项目有一个名为urls .py的模块,其中需要在personal_portfolio/url.py中包含hello_world应用程序的URL配置,添加以下内容:
personal_portfolio/urls.py

from django.contrib import admin
# from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
   # path('', include('hello_world.urls')),
]

这将在hello_world应用程序中**查找一个名为url.py的模块,并注册其中定义的任何url。**无论何时访问URL的根路径(localhost:8000), hello_world应用程序的URL都将被注册。hello_world.url模块还不存在,所以你需要创建它。

在这个模块中,我们需要导入path对象以及应用程序的视图模块。然后,我们想创建一个URL模式列表,它对应于各种视图函数。目前,我们只创建了一个视图函数,所以我们只需要创建一个URL:
hello_world/urls.py

from django.urls import path
from hello_world import views

urlpatterns = [
    path('', views.hello_world, name='hello_world'),
]

现在,当您重启服务器并访问localhost:8000时,您应该能够看到您创建的HTML模板:
在这里插入图片描述

您已经创建了您的第一个Django应用程序并将其连接到您的项目。不要忘记查看本节和前一节的源代码。现在唯一的问题是它看起来不太好。

添加Bootstrap 到你的app

如果您不添加任何样式,那么您创建的应用程序将不会看起来太漂亮。在本教程中,我们不讨论CSS样式,而只讨论如何将引导样式添加到项目中。这将使我们无需太多的努力就能改善网站的外观。

在开始引导样式之前,我们将创建一个基本模板,可以将其导入到每个后续视图。接下来,我们将在这个模板中添加引导样式导入。

创建另一个名为templates的目录(这次是在personal_portfolio中)和一个名为base.html在新目录中。

$ mkdir personal_portfolio/templates/
$ touch personal_portfolio/templates/base.html

我们创建了这个附加的模板目录来存储将在项目中的每个Django应用程序中使用的HTML模板。正如您前面看到的,每个Django项目可以由多个处理分离逻辑的应用程序组成,每个应用程序都包含自己的模板目录来存储与应用程序相关的HTML模板。

这种应用程序结构对于后端逻辑非常有效,但是我们希望整个站点在前端看起来一致。我们可以创建一个或一组由所有应用程序共享的模板,而不必将引导样式导入到每个应用程序中。只要Django知道在这个新的共享目录中寻找模板,它就可以保存许多重复的样式。

在这个新文件**(personal_portfolio/templates/base.html)**中,添加以下代码行:

{% block page_content %}{% endblock %}

现在,在hello_world/templates/hello_world.html,我们可以扩展这个基本模板:

{% extends "base.html" %}

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

这里发生的是,page_content块中的任何HTML都被添加到base.html中的相同块中。

要在应用程序中安装引导程序,您将使用 Bootstrap CDN。这是一种非常简单的安装引导程序的方法,只需要在base.html中添加几行代码。查看源代码,了解如何将CDN链接添加到项目中。

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

{% block page_content %}{% endblock %}

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>

我们创建的所有未来模板都将扩展base.html,这样我们就可以在每个页面上包含引导样式,而不必再次导入样式。

在看到新样式的应用程序之前,我们需要告诉Django项目base.html已经存在。默认设置在每个应用程序中注册模板目录,但不在项目目录中。在personal_portfolio/settings.py,更新模板:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
       # 添加这个 "DIRS": ["personal_portfolio/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",
            ]
        },
    }
]

现在,当您访问localhost:8000时,应该会看到页面的格式略有不同:
在这里插入图片描述
无论何时,只要您想要创建模板或导入您打算在项目中的所有Django应用程序中使用的脚本,您都可以将它们添加到这个项目级目录中,并在应用程序模板中扩展它们。

添加模板是构建Hello, World的最后一个阶段!Django的网站。您了解了Django模板引擎的工作原理,以及如何创建可以由Django项目中的所有应用程序共享的项目级模板。

在本节中,您学习了如何创建一个简单的Hello, World!Django站点通过使用一个应用程序创建一个项目。在下一节中,您将创建另一个应用程序来展示web开发项目,您将学习Django中的所有模型。

展示你的项目

任何希望创建投资组合的web开发人员都需要一种方式来展示他们所从事的项目。这就是你现在要做的。您将创建另一个Django应用程序projects,它将包含一系列将显示给用户的示例项目。用户可以单击projects,查看关于您工作的更多信息。

在构建项目应用程序之前,让我们先删除hello_world应用程序。你需要做的就是删除hello_world目录,并从settings.py中的INSTALLED_APPS中删除行“hello_world”。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello_world',  # Delete this line
]

最后,您需要删除在personal_portfolio/ URL .py中创建的URL路径:
personal_portfolio/urls.py:

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('hello_world.urls')),  # Delete this line
]

现在您已经删除了hello_world应用程序,我们可以创建projects应用程序。

$ python manage.py startapp projects

这将创建一个名为projects的目录。创建的文件与我们设置hello_world应用程序时创建的文件相同。为了连接我们的应用程序,我们需要将它添加到INSTALLED_APPS In settings.py:

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

在GitHub上查看本节的源代码。我们现在还不需要担心这个应用程序的url。相反,我们将专注于构建一个项目模型。

项目应用:模型

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

ORM是一个程序,允许您创建与数据库表相对应的类。类属性对应于列,类的实例对应于数据库中的行。因此,我们不需要学习一门全新的语言来创建数据库及其表,我们只需要编写一些Python类。

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

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

您将创建的模型将被称为Project,并具有以下字段:

  • title将是一个短字符串字段,用于保存项目的名称。
  • description将是一个较大的字符串字段,用于保存较长的文本。
  • technology将是一个string字段,但是它的内容将被限制在一个select数量的选项中。
  • image将是一个image字段,它包含存储图像的文件路径。

要创建这个模型,我们将在model .py中创建一个新类,并在我们的字段中添加以下内容:
model .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)
    image = models.FilePathField(path="/img")

Django模型带有许多内置的模型字段类型。我们在这个模型中只使用了三个。CharField用于短字符串并指定最大长度。

**TextField类似于CharField,但可以用于更长的表单文本,因为它没有最大长度限制。**最后,FilePathField还包含一个字符串,但必须指向一个文件路径名。

现在已经创建了项目类,我们需要Django来创建数据库。默认情况下,Django ORM在SQLite中创建数据库,但是您可以使用Django ORM使用其他使用SQL语言的数据库,比如PostgreSQL或MySQL。

要启动创建数据库的过程,需要创建migrationmigration是一个包含migration类的文件,其中包含告诉Django需要对数据库做哪些更改的规则。要创建迁移,在控制台中输入以下命令,确保您位于rp-portfolio目录中:

$ python manage.py makemigrations projects
Migrations for 'projects':
  projects/migrations/0001_initial.py
    - Create model Project

你应该看到在projects应用程序中创建了一个文件projects/migration /0001_initial.py

现在您已经创建了一个迁移文件,您需要应用迁移文件中列出的迁移,并使用迁移命令创建数据库:

$ python manage.py migrate projects
Operations to perform:
  Apply all migrations: projects
Running migrations:
  Applying projects.0001_initial... OK

注意:在运行makmigratemigrate命令时,我们在命令中添加了projects 。这告诉Django只查看projects 应用程序中的模型和迁移。Django附带了几个已经创建的模型。

如果您运行makmigration并在不使用projects标志的情况下迁移,那么Django项目中所有默认模型的所有迁移都将被创建和应用。这不是一个问题,但是对于本节的目的,不需要它们。

您还应该看到一个名为 db.sqlite3 是在项目的根目录中创建的。现在您的数据库已经设置好,可以运行了。现在您可以在您的表中创建行,这些行是您想要在投资组合站点上显示的各种项目。

要创建Project类的实例,我们必须使用Django shell。Django shell类似于Python shell,但是允许访问数据库并创建条目。要访问Django shell,我们使用另一个Django管理命令:

$ python manage.py shell

一旦您访问了shell,您将注意到命令提示符将从$更改为>>>。然后你可以导入你的模型:

>>> from projects.models import Project

我们首先要创建一个新的项目,具有以下属性:

  • name:我的第一个项目
  • description:一个web开发项目。
  • technology:Django
  • image:img / project1.png
    为此,我们在Django shell中创建了一个Project类的实例:
>>> p1 = Project(
...     title='My First Project',
...     description='A web development project.',
...     technology='Django',
...     image='img/project1.png'
... )
>>> p1.save()

这将在项目表中创建一个新条目,并将其保存到数据库中。现在您已经创建了一个可以在portfolio站点上显示的项目

本节的最后一步是创建另外两个示例项目:

>>> p2 = Project(
...     title='My Second Project',
...     description='Another web development project.',
...     technology='Flask',
...     image='img/project2.png'
... )
>>> p2.save()
>>> p3 = Project(
...     title='My Third Project',
...     description='A final development project.',
...     technology='Django',
...     image='img/project3.png'
... )
>>> p3.save()

现在您知道了如何在Django中创建模型并构建迁移文件,以便将这些模型类转换为数据库表。您还使用Django shell 创建了模型类的三个实例

在下一节中,我们将使用您创建的这三个项目并创建一个视图函数,以便在web页面上向用户显示它们。您可以在GitHub上找到本教程这一部分的源代码。

项目应用:视图

现在您已经创建了要在portfolio站点上显示的项目,您需要创建视图函数来将数据从数据库发送到HTML模板。

在projects应用程序中,您将创建两个不同的视图:

  1. 索引视图,显示每个项目的信息片段
  2. 显示特定主题的更多信息的详细视图

让我们从index视图开始,因为逻辑稍微简单一些。在views.py,您需要从models.py导入Project类,并创建一个project_index()函数,该函数呈现一个名为project_index.html的模板。在这个函数的主体中,您将使用Django ORM查询来选择Project表中的所有对象:

from django.shortcuts import render
from projects.models import Project

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

在这个代码块中有很多事情要做,让我们把它分解一下。

在第6行中,执行一个查询。查询只是一个命令,允许您在数据库中创建、检索、更新或删除对象(或行)。在本例中,您正在检索projects表中的所有对象。
数据库查询返回与查询匹配的所有对象的集合,称为Queryset。在本例中,您希望表中包含所有对象,因此它将返回所有projects的集合。

在上面代码块的第7行中,我们定义了一个字典上下文。字典只有一个条目项目,我们将包含所有项目的Queryset分配给它。上下文字典用于向模板发送信息。您创建的每个视图函数都需要有一个上下文字典

在第10行中,context作为一个参数添加到render()。只要将上下文参数传递给render(),模板中就可以使用上下文字典中的任何条目。您需要创建一个上下文字典,并在创建的每个视图函数中传递它来呈现。

我们还呈现了一个名为project_index.html的模板,它还不存在。现在不用担心这个。在下一节中,您将为这些视图创建模板。

接下来,您需要创建project_detail()视图函数。这个函数需要一个额外的参数:正在查看的项目的id。

否则,逻辑是相似的:

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

在第14行,我们执行另一个查询。**此查询检索主键pk等于函数参数中的主键pk的项目。**然后在上下文字典中分配该项目,并将其传递给render()。同样,这里有一个模板project_detail.html,我们还没有创建。

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

from django.urls import path
from . import views

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

在第5行中,我们将应用程序的根URL连接到project_index视图。连接project_detail视图稍微复杂一些。为此,我们希望URL是/1或/2,依项目的pk而定。

URL中的pk值与传递给视图函数的pk值相同,因此需要根据要查看的项目动态生成这些URL。为此,我们使用了int:pk表示法。这只是告诉Django URL中传递的值是一个整数,它的变量名是pk

现在已经设置好了这些url,我们需要将这些url连接到项目url。在personal_portfolio / url.py,添加以下突出显示的代码行:

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

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

这行代码包含了projects应用程序中的所有url,但这意味着当以projects/作为前缀时可以访问它们。现在有两个完整的url可以访问我们的项目:

  • localhost:8000/projects:项目索引页
  • localhost:8000/projects/3: pk=3的项目详细视图
    这些url仍然不能正常工作,因为我们没有任何HTML模板。但是我们的视图和逻辑已经启动并运行,所以剩下要做的就是创建这些模板。如果您想检查代码,请查看本节的源代码。

项目应用:模板

我们的最后一步是创建两个模板:

  1. project_index模板
  2. project_detail模板
    由于我们已经向应用程序添加了引导样式,我们可以使用一些预样式化的组件使视图看起来很漂亮。让我们从project_index模板开始。
    对于project_index模板,您将创建一个Bootstrap cards,每个Bootstrap cards显示项目的详细信息。当然,我们不知道会有多少项目。从理论上讲,可能会有数百个。

我们不想为每个项目创建100个不同的Bootstrap cards和硬编码所有信息。相反,我们将使用Django模板引擎的一个特性:for循环。

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

{% for project in projects %}
{# Do something... #}
{% endfor %}

现在您已经了解了for循环的工作原理,您可以将以下代码添加到名为projects/templates/project_index.html的文件中:

{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>Projects</h1>
<div class="row">
{% for project in projects %}
    <div class="col-md-4">
        <div class="card mb-2">
            <img class="card-img-top" src="{% static project.image %}">
            <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 %}

这里有很多引导HTML。如果您有兴趣了解更多信息,请随意复制和粘贴并查看引导文档。在这个代码块中,有几件事情需要突出显示,而不是关注引导程序。

在第1行中,我们像在Hello, World中那样扩展base.html 应用教程。我在这个文件中添加了一些样式,包括一个导航栏,这样所有的内容都包含在一个引导容器中。对base.html的更改可以在GitHub的源代码中看到。

在第2行,我们包含一个**{% load static %}标记来包含静态文件**,比如图像。还记得在Django模型一节中创建项目模型时的情况吗?它的一个属性是filepath。这个filepath是我们要为每个项目存储实际图像的地方。

Django自动注册存储在每个应用程序中名为static/的目录中的静态文件。我们的图像文件路径名的结构是:img/<photo_name>.png

当加载静态文件时,Django在静态/目录中查找与static/中的给定文件路径匹配的文件。因此,我们需要创建一个名为static/的目录,其中包含另一个名为img/的目录。在img/中,您可以从GitHub上的源代码复制图像。

在第6行,我们开始for循环,遍历上下文字典传入的所有项目。

在这个for循环中,我们可以访问每个单独的项目。要访问项目的属性,可以在双花括号内使用点符号。例如,要访问项目的标题,可以使用{{project.title}}。可以使用相同的符号访问项目的任何属性。

在第9行,我们包含了项目图像。在src属性中,我们添加代码**{% static project.image%}。这告诉Django在静态文件中查找匹配project.imfage**的文件。

我们需要强调的最后一点是第13行中的链接。这是到project_detail页面的链接。**在Django中访问url类似于访问静态文件。**网址代码如下:

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

在本例中,我们将访问一个名为project_detail的URL路径,该路径接受与项目pk号对应的整数参数。

所有这些就绪之后,如果您启动Django服务器并访问localhost:8000/projects,那么您应该会看到如下内容:
在这里插入图片描述
有了project_index.html模板,就可以创建project_detail.html模板了。这个模板的代码如下:

{% extends "base.html" %}
{% load static %}

{% block page_content %}
<h1>{{ project.title }}</h1>
<div class="row">
    <div class="col-md-8">
        <img src="{% static project.image %}" alt="" width="100%">
    </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 %}

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

如果您访问localhost:8000/projects/1,您应该会看到您创建的第一个项目的详细信息页面:
在这里插入图片描述
在本节中,您学习了如何使用模型、视图和模板为您的个人投资组合项目创建一个功能完整的应用程序。在GitHub上查看本节的源代码。

您将为您的站点构建一个功能完整的博客,还将了解Django管理页面和表单。

通过博客分享你的知识

博客是一个伟大的除了任何个人投资组合网站。无论你是每月更新还是每周更新,它都是一个分享你所学知识的好地方。在本节中,你将建立一个功能齐全的博客,让你可以执行以下任务:

  • 创建、更新和删除博客文章
  • 以索引视图或详细视图的形式向用户显示帖子
  • 为职位分配类别
  • 允许用户评论帖子

您还将学习如何使用Django管理界面,在这里您将根据需要创建、更新和删除文章和类别。

在开始构建站点这一部分的功能之前,先创建一个名为blog的Django应用程序。不要删除项目。你会想要在你的Django项目中的两个应用程序:

$ python manage.py startapp blog

这可能会让你感到熟悉,因为这是你第三次这么做了。别忘了在personal_porfolio/settings.py中将博客添加到你的INSTALLED_APPS中。

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "projects",
    "blog",
]

暂时不要连接url。与projects应用程序一样,您将从添加模型开始。

博客应用:模型

这个应用程序中的models.py文件比projects应用程序中的复杂得多。

你需要三个单独的数据库表为博客:

  • 帖子
  • 类别
  • 评论
    这些表需要相互关联。这样做更容易,因为Django模型带有专门用于此目的的字段。
from django.db import models
# 目录
class Category(models.Model):
    name = models.CharField(max_length=20)
# 推送的文章
class Post(models.Model):
    title = models.CharField(max_length=255)
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    categories = models.ManyToManyField('Category', related_name='posts')

Category模型非常简单。只需要一个CharField,其中存储Category的名称。
Post模型上的titlebody字段与项目模型中使用的字段类型相同。我们只需要一个CharField作为标题,因为我们只需要一个短字符串作为post标题。正文需要是一段很长的文本,所以我们使用TextField

接下来的两个字段created_onlast_modifiedDjango DateTimeFields类型。它们存储一个datetime对象,其中分别包含创建和修改post的日期和时间。

在第11行,DateTimeField接受一个参数auto_now_add=True。每当创建该类的实例时,将当前日期和时间分配给该字段。

在第12行,DateTimeField接受一个参数auto_now=True。每当保存该类的实例时,将当前日期和时间分配给该字段。这意味着每当编辑该类的实例时, date_modified都会更新。

post模型上的最后一个字段是最有趣的。我们希望以一种可以将许多类别分配给许多帖子的方式来链接类别和帖子的模型。幸运的是,Django通过提供一个ManytoManyField字段类型使我们更容易实现这一点。该字段链接PostCategory模型,并允许我们在两个表之间创建关系。

ManyToManyField有两个参数。第一个是关系所在的模型,在本例中是关系的类别。第二个允许我们从Category对象访问关系,即使我们没有在那里添加字段。通过添加贴子的related_name,我们可以访问类别。给我们该类别的文章列表。

我们需要添加的第三个也是最后一个模型是Comment。我们将使用另一个类似于ManyToManyField的关系字段来关联PostCategory。然而,我们只希望这种关系往一个方向发展:一个帖子应该有很多评论。

在定义了Comment类之后,您将看到它是如何工作的:

# 评论
class Comment(models.Model):
    author = models.CharField(max_length=60)
    body = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    post = models.ForeignKey('Post', on_delete=models.CASCADE)

这个模型的前三个字段看起来应该很熟悉。有一个author字段供用户添加名称或别名,一个body字段用于评论主体,还有一个created_on字段,它与Post模型上的created_on字段相同。

在第20行,我们使用另一个关系字段,ForeignKey字段。这类似于ManyToManyField,但它定义了多对一的关系。这背后的原因是,许多评论可以分配到一个帖子。但是你不能有一个与许多帖子相对应的评论。

ForeignKey字段接受两个参数。第一个是关系中的另一个模型,在本例中是Post。第二个命令告诉Django当一个帖子被删除时应该做什么。如果一个帖子被删除了,那么我们不希望与之相关的评论出现。因此,我们也想删除它们,所以我们添加了参数on_delete=models.CASCADE

一旦创建了模型,就可以使用makmigration创建迁移文件:

$ python manage.py makemigrations blog

最后一步是迁移表。这一次,不要添加特定于应用程序的标志。稍后,您将需要Django为您创建的用户模型:

$ python manage.py migrate

现在您已经创建了模型,我们可以开始添加一些帖子和类别。您将不会像在项目中那样从命令行执行此操作,因为在命令行中键入完整的博客文章至少是不愉快的!
相反,您将学习如何使用Django Admin,它将允许您在一个漂亮的web界面中创建模型类的实例。

博客应用:Django Admin

Django管理是一个非常棒的工具,也是使用Django的最大好处之一。因为您是惟一要编写博客文章和创建类别的人,所以没有必要创建用户界面来完成此任务。

另一方面,您不希望必须在命令行中编写博客文章。这就是Admin的作用。它允许您创建、更新和删除模型类的实例,并为此提供了一个很好的接口。

在访问admin之前,您需要将自己添加为超级用户。这就是为什么在上一节中,您应用了整个迁移项目,而不仅仅是应用程序。Django提供了内置的用户模型和用户管理系统,允许您登录到admin。

首先,您可以使用以下命令将自己添加为超级用户:

$ python manage.py createsuperuser

然后系统会提示您输入用户名、电子邮件地址和密码。一旦您输入了所需的详细信息,就会收到创建超级用户的通知。如果你犯了错误,不要担心,因为你可以重新开始:

Username (leave blank to use 'jasmine'): jfiner
Email address: jfiner@example.com
Password:
Password (again):
Superuser created successfully.

然后你打开localhost:8000 会看到以下的页面:
在这里插入图片描述

应该会出现User和Groups模型,但是您会注意到没有对您自己创建的模型的引用。这是因为您需要在admin中注册它们。

在博客目录中,打开admin.py文件并输入以下代码行:

from django.contrib import admin
from blog.models import Post, Category

class PostAdmin(admin.ModelAdmin):
    pass

class CategoryAdmin(admin.ModelAdmin):
    pass

admin.site.register(Post, PostAdmin)
admin.site.register(Category, CategoryAdmin)

在第2行,导入要在管理页面上注册的模型。

**注意:**我们不向管理员添加评论。这是因为通常没有必要自己编辑或创建评论。
如果您想要添加评论被调节的特性,那么也可以添加评论模型。步骤完全相同!

在第5行和第9行,您定义了空类PostAdmin和CategoryAdmin。出于本教程的目的,您不需要向这些类添加任何属性或方法。它们用于自定义管理页面上显示的内容。对于本教程,默认配置就足够了。

最后两行是最重要的。这些将模型注册到管理类。如果您现在访问localhost:8000/admin,那么您应该会看到Post和Category模型现在是可见的:

如果您单击进入Posts或category,您应该能够添加这两个模型的新实例。我喜欢使用lorem ipsum虚拟文本来添加虚假博客文章的文本。

在进入下一节之前,创建几个伪贴子并为它们分配伪类别。这样,当我们创建模板时,您就可以查看帖子了。

博客应用:视图

您需要在blog目录中的views.py文件中创建三个视图函数:

  • blog_index将显示所有文章的列表。
  • blog_detail将显示完整的文章、评论和一个允许用户创建新评论的表单。
  • blog_category将类似于blog_index,但是所查看的文章只属于用户选择的特定类别。

最简单的视图函数是blog_index()。这将非常类似于您的项目应用程序中的project_index()视图。您只需查询Post模型并检索它的所有对象:

from django.shortcuts import render
from blog.models import Post

def blog_index(request):
    posts = Post.objects.all().order_by('-created_on')
    context = {
        "posts": posts,
    }
    return render(request, "blog_index.html", context)

在第3行,导入Post模型,在视图函数的第6行,获得一个Queryset,其中包含数据库中的所有Post。order_by()根据给定的参数对Queryset进行排序。负号告诉Django **从最大的值开始,**而不是从最小的值开始。我们使用这个方法,因为我们希望首先对最近的帖子进行排序。

最后,定义上下文字典并呈现模板。不要担心创建它。您将在下一节中创建它们。

接下来,您可以开始创建**blog_category()**视图。view函数需要使用一个类别名称作为参数,并查询已分配给给定类别的所有职位的职位数据库:

def blog_category(request, category):
    posts = Post.objects.filter(
        categories__name__contains=category
    ).order_by(
        '-created_on'
    )
    context = {
        "category": category,
        "posts": posts
    }
    return render(request, "blog_category.html", context)

在第14行,您使用了Django Queryset过滤器。过滤器的参数告诉Django检索对象需要满足哪些条件。在本例中,我们只希望其类别包含与view函数的参数中给定的名称对应的类别的帖子。同样,您使用**order_by()**从最近的帖子开始排序。

然后,我们将这些文章和类别添加到上下文字典中,并呈现我们的模板。

要添加的最后一个视图函数是blog_detail()。这更复杂,因为我们要包含一个表单。在添加表单之前,只需设置view函数来显示带有与其关联的注释的特定post。这个函数几乎等同于projects app中的**project_detail()**视图函数:

def blog_detail(request, pk):
    post = Post.objects.get(pk=pk)
    comments = Comment.objects.filter(post=post)
    context = {
        "post": post,
        "comments": comments,
    }

    return render(request, "blog_detail.html", context)

view函数接受一个pk值作为参数,在第22行,用给定的pk检索对象。

在第23行,我们再次使用Django过滤器检索分配给给定文章的所有注释。

最后,将post和comments添加到上下文字典并呈现模板。
要向页面添加表单,需要在博客目录forms.py中创建另一个文件。 Django表单与模型非常相似。表单由一个类组成,其中类属性是表单字段。Django提供了一些内置的表单字段,您可以使用这些字段快速创建所需的表单。
对于这个表单,您只需要author(应该是CharField)和body(也可以是CharField)。

**注意:**如果表单的CharField对应于模型CharField,请确保两者具有相同的max_length值。

blog/forms.py应该包含以下代码:

from django import forms

class CommentForm(forms.Form):
    author = forms.CharField(
        max_length=60,
        widget=forms.TextInput(attrs={
            "class": "form-control",
            "placeholder": "Your Name"
        })
    )
    body = forms.CharField(widget=forms.Textarea(
        attrs={
            "class": "form-control",
            "placeholder": "Leave a comment!"
        })
    )

您还将注意到一个参数小部件被传递到这两个字段。author字段有表单。TextInput小部件。这告诉Django将该字段作为HTML文本输入元素加载到模板中。body字段使用表单。而是TextArea小部件,以便将字段呈现为HTML文本区域元素。

这些小部件还接受一个参数attrs,它是一个字典,允许我们指定一些CSS类,这将有助于稍后格式化该视图的模板。它还允许我们添加一些占位符文本

当表单被发布时,POST请求被发送到服务器。因此,在view函数中,我们需要检查是否已接收到POST请求。然后,我们可以从表单字段创建注释。Django的表单上提供了一个方便的is_valid(),因此我们可以检查是否正确输入了所有字段。

从表单创建评论之后,需要使用save()保存它,然后查询数据库,查找分配给给定post的所有评论。你的视图函数应该包含以下代码:

def blog_detail(request, pk):
    post = Post.objects.get(pk=pk)
	# 获取/验证表单
    form = CommentForm()
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = Comment(
                author=form.cleaned_data["author"],
                body=form.cleaned_data["body"],
                post=post
            )
            comment.save()

    comments = Comment.objects.filter(post=post)
    context = {
        "post": post,
        "comments": comments,
        "form": CommentForm(), # 添加表单
    }
    return render(request, "blog_detail.html", context)

在第25行,我们创建了一个表单类的实例。不要忘记在文件开头导入表单:

from . import CommentForm

然后,我们继续检查是否收到了POST请求。如果有,则创建表单的新实例,用表单中输入的数据填充。

然后使用is_valid()验证表单。如果表单有效,则创建一个新的Comment实例。您可以使用表单访问表单中的数据。cleaned_data,这是一个字典。

字典的这些键对应于表单字段,因此可以使用**form.cleaned_data[‘author’]**访问作者。创建评论时,不要忘记将当前的帖子添加到评论中。

注意: 提交表单的生命周期可能有点复杂,下面是它的工作原理:

  1. 当用户访问包含表单的页面时,他们向服务器发送 GET请求。 在本例中,表单中没有输入数据,因此我们只想呈现表单并显示它。

  2. 当用户输入信息并单击Submit按钮时,将向服务器发送包含与表单一起提交的数据的POST请求。此时,必须处理数据,可能发生两种情况:

    • 表单是有效的,用户被重定向到下一页。
    • 表单无效,将再次显示空表单。用户回到步骤1,然后重复这个过程。

    **Django表单模块将输出一些错误,您可以将这些错误显示给用户。**这超出了本教程的范围,但是您可以在Django文档中阅读关于呈现表单错误消息的更多信息。

在第34行,保存注释,然后将form添加到上下文字典中,这样您就可以在HTML模板中访问表单了。

在创建模板并实际查看这个博客并运行之前的最后一步是连接url。您需要在blog/中创建另一个url .py文件,并为三个视图添加url:

from django.urls import path
from . import views

urlpatterns = [
    path("", views.blog_index, name="blog_index"),
    path("<int:pk>/", views.blog_detail, name="blog_detail"), # blog_detail 路径
    path("<category>/", views.blog_category, name="blog_category"),# blog_category 目录
]

一旦有了特定于blog的URL,您需要使用include()将它们添加到项目URL配置中:

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

urlpatterns = [
    path("admin/", admin.site.urls),
    path("projects/", include("projects.urls")),
    path("blog/", include("blog.urls")), #添加blog.urls
]

设置好后,所有的博客URL都将前缀为blog/,您将拥有以下URL路径:

  • localhost: 8000 / blog:博客索引
  • localhost:8000/blog/1:pk值为1的博客内容
  • localhost:8000/blog/python:所有带有python类别的文章的blog索引视图

这些url还不能工作,因为您仍然需要创建模板。

在本节中,您为博客应用程序创建了所有视图。您学习了如何在查询时使用过滤器,以及如何创建Django表单。不久你就能看到你的博客应用程序的运行了!

博客应用:模板

我们博客应用程序的最后一部分是模板。在本节结束时,您将创建一个功能完整的博客。

您将注意到模板中包含了一些引导元素,以使界面更美观。这些并不是本教程的重点,所以我略过了它们的作用,但是请查看引导文档了解更多信息。

您将创建的第一个模板是博客**/templates/blog_index.html新文件中的博客索引。这与projects index**视图非常相似。

您将使用for循环遍历所有的post。对于每个帖子,您都将显示标题和正文片段。与往常一样,您将扩展基本模板personal_porfolio/templates/base.html,其中包含我们的导航栏和一些额外的格式:

{% extends "base.html" %}
{% block page_content %}
<div class="col-md-8 offset-md-2">
    <h1>Blog Index</h1>
    <hr>
    {% for post in posts %}
    <h2><a href="{% url 'blog_detail' post.pk%}">{{ post.title }}</a></h2>
    <small>
        {{ post.created_on.date }} |&nbsp;
        Categories:&nbsp;
        {% for category in post.categories.all %}
        <a href="{% url 'blog_category' category.name %}">
            {{ category.name }}
        </a>&nbsp;
        {% endfor %}
    </small>
    <p>{{ post.body | slice:":400" }}...</p>
    {% endfor %}
</div>
{% endblock %}

在第7行,我们有一个post标题,它是一个超链接。这个链接是一个Django链接,我们指向名为blog_detail的URL,它的参数是一个整数,应该与文章的pk值相对应。

在标题下面,我们将显示文章的created_on属性及其类别。在第11行,我们使用另一个for循环遍历分配给post的所有类别。

在第17行,我们使用一个模板过滤器片将post主体剪切为400个字符,这样博客索引的可读性更强。

一旦设置好了,您应该能够通过访问localhost:8000/blog访问这个页面:
在这里插入图片描述
接下来,创建另一个HTML文件blog/templates/blog_category. HTML,其中将包含blog_category模板。这应该与blog_index相同。html,除了类别名称在h1标签内而不是博客索引:

{% extends "base.html" %}
{% block page_content %}
<div class="col-md-8 offset-md-2">
    <h1>{{ category | title }}</h1>
    <hr>
    {% for post in posts %}
        <h2><a href="{% url 'blog_detail' post.pk%}">{{ post.title }}</a></h2>
        <small>
            {{ post.created_on.date }} |&nbsp;
            Categories:&nbsp;
            {% for category in post.categories.all %}
            <a href="{% url 'blog_category' category.name %}">
                {{ category.name }}
            </a>&nbsp;
            {% endfor %}
        </small>
        <p>{{ post.body | slice:":400" }}...</p>
    {% endfor %}
</div>
{% endblock %}

这个模板的大部分与前面的模板相同。惟一的区别是在第4行,我们使用了另一个Django模板过滤器title。这将titlecase应用于字符串,并使单词以大写字母开头

完成该模板后,您将能够访问category视图。如果您定义了一个名为python的类别,您应该能够访问localhost:8000/blog/python并查看该类别的所有文章:
在这里插入图片描述
要创建的最后一个模板是post_detail模板。在这个模板中,您将显示文章的标题全文

在文章的标题和正文之间,您将显示文章创建的日期和任何类别。在这下面,您将包含一个comments表单,以便用户可以添加新的评论。在此之下,将会有一份已经留下的评论清单:

{% extends "base.html" %}
{% block page_content %}
<div class="col-md-8 offset-md-2">
    <h1>{{ post.title }}</h1>
    <small>
        {{ post.created_on.date }} |&nbsp;
        Categories:&nbsp;
        {% for category in post.categories.all %}
        <a href="{% url 'blog_category' category.name %}">
            {{ category.name }}
        </a>&nbsp;
        {% endfor %}
    </small>
    <p>{{ post.body | linebreaks }}</p>
    <h3>Leave a comment:</h3>
    <form action="/blog/{{ post.pk }}/" method="post">
        {% csrf_token %}
        <div class="form-group">
            {{ form.author }}
        </div>
        <div class="form-group">
            {{ form.body }}
        </div>
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    <h3>Comments:</h3>
    {% for comment in comments %}
    <p>
        On {{comment.created_on.date }}&nbsp;
        <b>{{ comment.author }}</b> wrote:
    </p>
    <p>{{ comment.body }}</p>
    <hr>
    {% endfor %}
</div>
{% endblock %}

显示文章标题、日期和类别的模板的前几行逻辑与前面的模板相同。这一次,在呈现post主体时,使用换行模板过滤器。此标记将换行符注册为新段落,因此主体不会显示为一个长文本块。

在帖子下面,第16行,您将显示您的表单。表单操作指向要将POST请求发送到的页面的URL路径。在本例中,它与当前正在访问的页面相同。然后添加csrf_token,它提供安全性,并呈现表单的主体和作者字段,然后是submit按钮。

要获得authorbody字段的引导样式,您需要将表单控制类添加到文本输入中。

因为Django在您包含{{ form.body }} 和 {{ form.author }},您不能在模板中添加这些类。这就是为什么在前一节中向表单小部件添加属性的原因。

在表单下面,有另一个for循环,它循环遍历给定帖子上的所有评论。将显示评论、主体、作者和created_on属性。
一旦模板就位,您应该能够访问localhost:8000/blog/1并查看您的第一篇文章:
在这里插入图片描述
您还应该能够通过单击blog_index视图中的标题来访问文章的详细信息页面。

最后一项操作是将blog_index链接添加到base.html中的导航栏。这样,当您在导航栏中单击Blog时,您将能够访问Blog。查看源代码中对base.html的更新,了解如何添加该链接。

现在,您的个人投资组合站点已经完成,您已经创建了您的第一个Django站点。包含所有特性的源代码的最终版本可以在GitHub上找到,所以请查看!点击周围的网站一点,看看所有的功能,并尝试留下一些评论您的帖子!

你可能会在这里或那里发现一些你认为需要打磨的东西。去把它们整理一下。了解这个web框架的最佳方法是通过实践,所以请尝试扩展这个项目,使它变得更好!如果您不确定从哪里开始,我在下面的结论中为您留下了一些想法!

结论

我们已经讲了很多,所以一定要继续练习和构建。构建得越多,就会变得越容易,您需要回头查看本文或文档的次数就越少。您将很快构建复杂的web应用程序。
在本教程中,您已经看到:

  • 如何创建Django项目和应用程序
  • 如何添加带有视图和模板的web页面
  • 如何使用表单获取用户输入
  • 如何将视图和模板与URL配置挂钩
  • 如何使用带有Django对象关系映射器的关系数据库向站点添加数据
  • 如何使用Django管理来管理您的模型
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值