网页版项目
我不了解您,但就我个人而言,通过查看实际示例和代码片段,我学到了更多。对我来说,这是难以处理在在例子你读一个概念 Class A
和 Class B
,或者当我看到经典的 foo(bar)
例子。我不想和你做那种事。
所以,在我们进入有趣的部分之前,先玩玩模型、视图和所有东西。让我们花点时间简要讨论一下我们将要开发的这个项目。
如果您已经有 Web 开发经验并且觉得它的细节太多,您可以浏览图片以了解我们将要构建的内容,然后跳转到本教程的模型 部分。
但是,如果您不熟悉 Web 开发,我强烈建议您继续阅读。它将为您提供有关 Web 应用程序建模和设计的一些很好的见解。Web 开发和一般的软件开发不仅仅是编码。
火箭科学
用例图
我们的项目是一个讨论板(一个论坛)。整个想法是维护几个board ,它们的行为类似于类别。然后,在特定板内,用户可以通过创建新主题 来开始新的讨论。在该主题中,其他用户可以参与讨论发布回复。
我们需要找到一种方法来区分普通用户和管理员用户,因为只有管理员才能创建新的板。下面概述了我们的主要用例和每种类型用户的角色:
用例图
类图
从用例图中,我们可以开始考虑我们项目的实体 。实体是我们将要创建的模型,它与我们的 Django 应用程序将处理的数据密切相关。
为了能够实现上一节中描述的用例,我们至少需要实现以下模型:Board 、Topic 、Post 和User 。
基本类图
花时间思考模型如何相互关联也很重要。实线告诉我们的是,在Topic 中 ,我们需要有一个字段来标识它属于哪个Board 。同样,帖子 将需要一个字段来表示它属于哪个主题 ,以便我们可以在讨论中仅列出在特定主题中创建的帖子 。最后,我们需要在Topic和Post中的字段来了解谁发起了讨论,以便我们可以识别谁在发布回复。
我们还可以与Board 和User 模型建立关联,因此我们可以确定谁创建了给定的Board 。但此信息与应用程序无关。还有其他方法可以跟踪此信息,稍后您将看到。
现在我们有了基本的类表示,我们必须考虑每个模型将携带什么样的信息。这种事情很容易变得复杂。所以尽量把注意力集中在重要的地方。开始开发所需的信息。稍后,我们可以使用migrations 改进模型,您将在下一个教程中详细介绍。
但就目前而言,这将是我们模型字段的基本表示:
类图
这个类图强调模型之间的关系。这些线条和箭头最终将在以后转换为字段。
对于Board 模型,我们将从两个字段开始:name 和description 。该名称 字段必须是唯一的,所以要避免重复板的名称。该描述 只是给什么样的主板是所有关于一个提示。
该主题 模式将包括四个领域:主题 ,最后更新 日期将被用来定义主题排序,主题起动机 来识别用户 谁开始的主题 ,和一个叫做场板 来定义哪些主板 特定主题 属于.
该帖子 车型将拥有一个信息 场,这将是用于存储后答复的文本,在创建 日期和时间字段主要用来订购帖子 一内主题 ,一个在更新的 日期和时间栏通知用户 何时以及是否编辑了给定的帖子 。与日期和时间字段一样,我们还必须引用User 模型:由**.created** 和updated . 。
最后,用户 模型。在类图中,我只提到了字段username 、password 、email 和超级用户 标志,因为这几乎是我们现在要使用的全部内容。需要注意的是,我们不需要创建User 模型,因为 Django 已经在contrib包中内置了User 模型 。我们将使用它。
关于多重性在类图(数字 1
,0..*
等等),这里是你如何阅读:
类图板和主题关联一个主题必须与一个 ( 1
)板相关联(这意味着它不能为空),并且一个板可以与许多主题相关联或没有 ( 0..*
)相关联。这意味着Board可能没有单个Topic存在。
类图话题和帖子关联一个主题应该至少有一个帖子(起始帖子),它也可以有很多帖子(1..*
)。一个 帖子 必须与一个主题相关联,并且只能与一个主题( 1
)相关联。
类图主题和用户关联一个主题必须有一个且只有一个关联的用户:主题起始用户( 1
)。一个用户可能有很多或没有主题( 0..*
)。
类图帖子和用户关联一个帖子必须有一个并且只有一个用户与:创建者( 1
)相关联。一个用户可能有很多或没有 帖子( 0..*
)。Post和User之间的第二个关联是直接关联(参见行尾的箭头),这意味着我们只对关系的一侧感兴趣,即User编辑给定Post 的内容。它将被翻译成updated by字段。多重性表示0..1
,这意味着 更新的字段可能为空(Post未编辑)并且最多只能与一个User相关联。
绘制此类图的另一种方法是强调字段而不是模型之间的关系:
类图属性
图 4:强调类(模型)的属性(字段)的类图
上面的表示与上一个等效,也更接近我们将要使用 Django Models API 设计的内容。在这个表示中,我们可以更清楚地看到,在Post 模型中,关联 主题 、创建者 和更新者 成为模型字段。另一个需要注意的有趣的事情是,在 Topic 模型中,我们现在有一个名为posts()的操作 (一个类方法**)** 。我们将通过实现反向关系来实现这一点,其中 Django 将自动在数据库中执行查询以返回属于特定主题的所有帖子 的列表。
好的,现在足够的 UML!为了绘制本节中介绍的图表,我使用了 StarUML工具。
线框
在花了一些时间设计应用程序模型之后,我喜欢创建一些线框图来定义需要完成的工作,并清楚地了解我们要去哪里。
线框漫画
然后基于线框图,我们可以更深入地了解应用程序中涉及的实体。
首先,我们需要显示主页中的所有板:
线框板
图 5:电路板项目线框主页列出了所有可用的电路板。
如果用户点击一个链接,比如在 Django 面板中,它应该列出所有主题:
线框主题
图 6:Boards 项目线框,列出了 Django board 中的所有主题。
这里我们有两条主要路径:用户点击“新话题”按钮创建新话题,或者用户点击话题查看或参与讨论。
“新话题”画面:
线框新主题
图 7:新主题屏幕
现在是主题屏幕,显示帖子和讨论:
线框帖子
图 8:主题帖子列表屏幕
如果用户单击回复按钮,他们将看到下面的屏幕,其中包含反向顺序的帖子摘要(最新的在前):
线框回复
图 9:回复主题屏幕
要绘制线框,您可以使用draw.io服务,它是免费的。
Models
模型基本上是应用程序数据库布局的表示。我们将在本节中做的是创建我们在上一节中建模的类的 Django 表示:Board 、Topic 和Post 。该用户 模型中已经定义了一个内置的应用程序命名的权威性 ,这是我们列出 INSTALLED_APPS
的配置命名空间下django.contrib.auth 。
我们将在board/models.py 文件中完成所有工作。下面是我们如何表示我们的类图( 见图 4)。在 Django 应用程序中:
代码语言:javascript复制from django.db import models
from django.contrib.auth.models import User
class Board(models.Model):
name = models.CharField(max_length=30, unique=True)
description = models.CharField(max_length=100)
class Topic(models.Model):
subject = models.CharField(max_length=255)
last_updated = models.DateTimeField(auto_now_add=True)
board = models.ForeignKey(Board, related_name='topics')
starter = models.ForeignKey(User, related_name='topics')
class Post(models.Model):
message = models.TextField(max_length=4000)
topic = models.ForeignKey(Topic, related_name='posts')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
created_by = models.ForeignKey(User, related_name='posts')
updated_by = models.ForeignKey(User, null=True, related_name=' ')
所有模型都是django.db.models.Model 类的子类。每个类都会被转换成数据库表 。每个字段由django.db.models.Field 子类(内置 Django 核心)的实例表示,并将被转换为数据库列 。
fields CharField
、DateTimeField
等都是django.db.models.Field 的 子类,它们包含在 Django 核心中——随时可以使用。
在这里,我们仅使用 CharField
、TextField
、DateTimeField
和 ForeignKey
字段来定义我们的模型。但是 Django 提供了广泛的选项来表示不同类型的数据,例如 IntegerField
、BooleanField
、 DecimalField
等等。我们将根据需要引用它们。
某些字段具有必需的参数,例如 CharField
. 我们应该始终设置一个 max_length
. 此信息将用于创建数据库列。Django 需要知道数据库列需要多大。max_length
Django Forms API 也将使用该 参数来验证用户输入。稍后再谈。
在 Board
模型定义中,更具体地说是在 name
字段中,我们还设置了参数 unique=True
,顾名思义,它将在数据库级别强制执行字段的唯一性。
在 Post
模型中,该 created_at
字段有一个可选参数,auto_now_add
设置为 True
。这将指示 Django 在 Post
创建对象时设置当前日期和时间。
在模型之间创建关系的一种方法是使用 ForeignKey
字段。它将在模型之间创建链接并在数据库级别创建适当的关系。该 ForeignKey
字段需要一个位置参数,其中包含对其将相关的模型的引用。
例如,在 Topic
模型中,board
字段是 ForeignKey
给 Board
模型。它告诉 Django 一个 Topic
实例只与一个 Board
实例相关。该 related_name
参数将用于创建 反向关系 ,其中 Board
实例将有权访问 Topic
属于它的实例列表。
Django 会自动创建这种反向关系——这 related_name
是可选的。但是如果我们不为其设置名称,Django 将使用名称生成它:(class_name)_set
。例如,在 Board
模型中,Topic
实例将在 topic_set
属性下可用。相反,我们只是将其重命名为 topics
,使其感觉更自然。
在 Post
模型中,该 updated_by
字段设置 related_name=' '
. 这告诉 Django 我们不需要这种反向关系,所以它会忽略它。
您可以在下面看到类图和使用 Django 生成模型的源代码之间的比较。绿线代表我们如何处理反向关系。
类图模型定义
此时,您可能会问自己:“主键/ID 怎么样”?如果我们不为模型指定主键,Django 会自动为我们生成它。所以我们现在很好。在下一节中,您将更好地了解它是如何工作的。
迁移模型
下一步是告诉 Django 创建数据库,以便我们可以开始使用它。
打开命令行工具,激活虚拟环境,进入manage.py文件所在文件夹,运行以下命令:
代码语言:javascript复制python manage.py makemigrations
作为输出,您将得到如下内容:
代码语言:javascript复制Migrations for 'boards':
boards/migrations/0001_initial.py
- Create model Board
- Create model Post
- Create model Topic
- Add field topic to post
- Add field updated_by to post
在这一点上,Django的创建了一个名为文件0001_initial.py 内部电路板/迁移 目录。它代表我们应用程序模型的当前状态。在下一步中,Django 将使用此文件来创建表和列。
迁移文件被翻译成 SQL 语句。如果您熟悉 SQL,可以运行以下命令来检查将在数据库中执行的 SQL 指令:
代码语言:javascript复制python manage.py sqlmigrate boards 0001
如果您不熟悉 SQL,请不要担心。在本教程系列中,我们不会直接使用 SQL。所有的工作都将使用 Django ORM 完成,它是一个与数据库通信的抽象层。
现在下一步是将 我们生成的迁移应用到数据库:
代码语言:javascript复制python manage.py migrate
输出应该是这样的:
代码语言:javascript复制Operations to perform:
Apply all migrations: admin, auth, boards, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying boards.0001_initial... OK
Applying sessions.0001_initial... OK
因为这是我们第一次迁移数据库,该 migrate
命令还应用了来自 Django contrib 应用程序的现有迁移文件,列在 INSTALLED_APPS
. 这是预期的。
该行 Applying boards.0001_initial... OK
是我们在上一步中生成的迁移。
就是这样!我们的数据库已准备好使用。
SQLite
注意: 重要的是要注意SQLite 是一个生产质量的数据库。许多公司在数千种产品中使用 SQLite,例如所有 Android 和 iOS 设备、所有主要 Web 浏览器、Windows 10、macOS 等。
它只是不适合所有情况。SQLite 无法与 MySQL、PostgreSQL 或 Oracle 等数据库进行比较。大容量网站、写入密集型应用程序、非常大的数据集、高并发性,这些情况最终会导致使用 SQLite 出现问题。
我们将在项目开发期间使用 SQLite,因为它很方便,我们不需要安装任何其他东西。当我们将项目部署到生产环境时,我们将切换到 PostgreSQL。对于简单的网站,这很好用。但是对于复杂的网站,建议开发和生产使用同一个数据库。
版权属于:Cyril
本文链接:https://cloud.tencent.com/developer/article/1858341
转载时须注明出处及本声明