如何创建 Django 模型

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 如何创建 Django 模型

简介

在上一篇教程“如何创建 Django 应用程序并将其连接到数据库”中,我们介绍了如何创建一个 MySQL 数据库,如何创建和启动一个 Django 应用程序,以及如何将其连接到一个 MySQL 数据库。

在本教程中,我们将创建 Django 模型,定义我们将要存储的博客应用程序数据的字段和行为。这些模型将 Django 应用程序的数据映射到数据库。这是 Django 用来通过对象关系映射(ORM)API生成数据库表的方式,被称为“模型”。

先决条件

本教程是 Django 开发系列的一部分,是该系列的延续。

如果您没有跟随这个系列,我们做出以下假设:

  • 您已安装 Django 版本为 4 或更高版本。
  • 您已将 Django 应用程序连接到数据库。我们正在使用 MySQL,您可以通过跟随 Django 系列的第二部分“如何创建 Django 应用程序并将其连接到数据库”来实现这种连接。
  • 您正在使用基于 Unix 的操作系统,最好是 Ubuntu 22.04 云服务器,因为这是我们测试的系统。如果您想在类似的环境中设置 Django,请参考我们的教程“如何在 Ubuntu 22.04 上安装 Django 并设置开发环境”。

由于本教程主要涉及 Django 模型,即使您的设置有些不同,您也可以跟着做。

步骤 1 — 创建 Django 应用程序

为了与 Django 的模块化哲学保持一致,我们将在我们的项目中创建一个 Django 应用程序,其中包含创建博客网站所需的所有文件。

每当我们开始在 Python 和 Django 中工作时,我们应该激活我们的 Python 虚拟环境并进入我们的应用程序的根目录。如果您跟着这个系列,您可以通过输入以下内容来实现这一点。

cd ~/my_blog_app
. env/bin/activate
cd blog

然后,让我们运行以下命令:

python manage.py startapp blogsite

这将创建我们的应用程序以及一个 blogsite 目录。

在本教程系列的这一点上,您的项目将具有以下目录结构:

my_blog_app/
└── blog
    ├── blog
    │   ├── __init__.py
    │   ├── __pycache__
    │   │   ├── __init__.cpython-38.pyc
    │   │   ├── settings.cpython-38.pyc
    │   │   ├── urls.cpython-38.pyc
    │   │   └── wsgi.cpython-38.pyc
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── blogsite
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    └── manage.py

在本教程中,我们将专注于 models.py 文件,该文件位于 blogsite 目录中。

步骤 2 — 添加文章模型

首先,我们需要打开并编辑 models.py 文件,以便其中包含生成 Post 模型的代码。Post 模型包含以下数据库字段:

  • title — 博客文章的标题。
  • slug — 存储和生成网页的有效 URL。
  • content — 博客文章的文本内容。
  • created_on — 文章创建的日期。
  • author — 撰写文章的人。

现在,进入包含 models.py 文件的目录。

cd ~/my_blog_app/blog/blogsite

使用 cat 命令在终端中显示文件的内容。

cat models.py

文件应该包含以下代码,其中导入了模型,并包含了一个描述应该放入这个 models.py 文件的注释。

from django.db import models
# Create your models here.

使用您喜欢的文本编辑器,将以下代码添加到 models.py 文件中。我们将使用 nano 作为我们的文本编辑器,但您可以使用您喜欢的任何编辑器。

nano models.py

在这个文件中,已经添加了导入模型 API 的代码,我们可以继续删除后面的注释。然后,我们将导入 slugify 以从字符串生成 slug,Django 的 User 用于身份验证,以及从 django.urls 导入 reverse 以便更灵活地创建 URL。

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse

然后,在我们将要称为 Post 的模型类上添加类方法,其中包含以下数据库字段:titleslugcontentcreated_onauthor。将这些添加到您的导入语句下面。

...
class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.TextField()

接下来,我们将为生成 URL 添加功能,并为保存文章添加功能。这是至关重要的,因为这将创建一个唯一的链接来匹配我们的唯一文章。

...
    def get_absolute_url(self):
        return reverse('blog_post_detail', args=[self.slug])
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

现在,我们需要告诉模型帖子应该如何排序,并在网页上显示。这个逻辑将被添加到一个嵌套的内部 Meta 类中。Meta 类通常包含与数据库字段定义无关的其他重要模型逻辑。

...
    class Meta:
        ordering = ['created_on']
        def __unicode__(self):
            return self.title

最后,我们将在这个文件中添加 Comment 模型。这涉及添加另一个名为 Comment 的类,其签名中包含 models.Models,并定义以下数据库字段:

  • name — 发表评论的人的姓名。
  • email — 发表评论的人的电子邮件地址。
  • text — 评论本身的文本。
  • post — 发表评论的文章。
  • created_on — 评论创建的时间。
...
class Comment(models.Model):
    name = models.CharField(max_length=42)
    email = models.EmailField(max_length=75)
    website = models.URLField(max_length=200, null=True, blank=True)
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

到目前为止,models.py 将会完成。确保您的 models.py 文件与以下内容匹配:

from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.urls import reverse
class Post(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=255)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    author = models.TextField()
    def get_absolute_url(self):
        return reverse('blog_post_detail', args=[self.slug])
    
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)
    class Meta:
        ordering = ['created_on']
        def __unicode__(self):
            return self.title
class Comment(models.Model):
    name = models.CharField(max_length=42)
    email = models.EmailField(max_length=75)
    website = models.URLField(max_length=200, null=True, blank=True)
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now_add=True)

确保保存并关闭文件。如果您使用的是 nano,您可以通过输入 CTRLX,然后 Y,然后 ENTER 来完成。

有了设置好的 models.py 文件,我们可以继续更新我们的 settings.py 文件。

步骤 3 — 更新设置

现在我们已经向我们的应用程序添加了模型,我们必须告知我们的项目刚刚添加的 blogsite 应用程序的存在。我们通过将其添加到 settings.py 中的 INSTALLED_APPS 部分来实现这一点。

导航到包含您的 settings.py 的目录。

cd ~/my_blog_app/blog/blog

然后,使用 nano 或其他编辑器打开您的 settings.py 文件。

nano settings.py

打开文件后,按照下面的指示将您的 blogsite 应用程序添加到文件的 INSTALLED_APPS 部分。

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

添加了 blogsite 应用程序后,您可以保存并退出文件。

此时,我们已经准备好继续应用这些更改。

步骤 4 — 进行迁移

添加了我们的 PostComment 模型后,下一步是应用这些更改,以便我们的 MySQL 数据库模式识别它们并创建必要的表。

首先,我们必须使用 makemigrations 命令将我们的模型更改打包成单独的迁移文件。这些文件类似于版本控制系统(如 Git)中的提交。

现在,如果您导航到 ~/my_blog_app/blog/blogsite/migrations 并运行 ls 命令,您会注意到只有一个 __init__.py 文件。一旦我们添加了迁移,这将会改变。

使用 cd 切换到博客目录,如下所示:

cd ~/my_blog_app/blog

然后在 manage.py 上运行 makemigrations 命令。

python manage.py makemigrations

然后您将在终端窗口中收到以下输出:

Migrations for 'blogsite':
  blogsite/migrations/0001_initial.py
    - Create model Post
    - Create model Comment

记住,当我们导航到 /~/my_blog_app/blog/blogsite/migrations 时,它只有 __init__.py 文件?如果我们现在切换回该目录,我们会注意到已经添加了两个项目:__pycache__0001_initial.py。当您运行 makemigrations 时,0001_initial.py 文件会自动生成。每次运行 makemigrations 时都会生成类似的文件。

如果您想阅读文件的内容,请从所在目录运行 less 0001_initial.py

现在导航到 ~/my_blog_app/blog

cd ~/my_blog_app/blog

由于我们已经创建了迁移文件,我们必须使用 migrate 命令将这些文件描述的更改应用到数据库。但首先,让我们使用 showmigrations 命令检查当前存在哪些迁移。

python manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
blogsite
 [ ] 0001_initial
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
sessions
 [X] 0001_initial

您会注意到除了我们刚刚创建的 0001_initial 之外,所有迁移都已经被检查。

现在让我们使用以下命令检查一旦我们进行迁移将执行哪些 SQL 语句,它接受迁移和迁移的标题作为参数:

python manage.py sqlmigrate blogsite 0001_initial

下面显示了幕后实际执行的 SQL 查询。

--
-- Create model Post
--
CREATE TABLE `blogsite_post` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `title` varchar(255) NOT NULL, `slug` varchar(255) NOT NULL UNIQUE, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `author` longtext NOT NULL);
--
-- Create model Comment
--
CREATE TABLE `blogsite_comment` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `name` varchar(42) NOT NULL, `email` varchar(75) NOT NULL, `website` varchar(200) NULL, `content` longtext NOT NULL, `created_on` datetime(6) NOT NULL, `post_id` integer NOT NULL);
ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);

现在让我们执行迁移,以便将它们应用到我们的 MySQL 数据库。

python manage.py migrate

您将收到以下输出:

Operations to perform:
  Apply all migrations: admin, auth, blogsite, contenttypes, sessions
Running migrations:
  Applying blogsite.0001_initial... OK

您已成功应用了迁移。

请记住,根据 Django 文档,使用 MySQL 作为后端的 Django 迁移有三个注意事项。

  • 不支持围绕模式更改操作的事务。换句话说,如果迁移未成功应用,您将不得不手动取消您所做的更改,以尝试另一个迁移。无法回滚到在失败迁移之前的任何更改。
  • 对于大多数模式更改操作,MySQL 将完全重写表。在最坏的情况下,时间复杂度将与表中的行数成正比。根据 Django 文档,这可能慢到每百万行一分钟。
  • 在 MySQL 中,列、表和索引的名称长度有限制。所有列和索引覆盖的组合大小也有限制。虽然其他一些后端可以支持 Django 中创建的更高限制,但在使用 MySQL 后端时,相同的索引将无法创建。

对于您考虑用于 Django 的每个数据库,务必权衡各自的优缺点。

步骤 5 —— 验证数据库模式

迁移完成后,我们应该验证通过 Django 模型创建的 MySQL 表的成功生成。

为此,请在终端中运行以下命令以登录到 MySQL。我们将使用之前教程中创建的 djangouser

mysql blog_data -u djangouser

现在,选择我们的数据库 blog_data。如果你不知道正在使用的数据库,可以在 SQL 中使用SHOW DATABASES;来显示所有数据库。

USE blog_data;

然后输入以下命令以查看表。

SHOW TABLES;

这个 SQL 查询应该会显示以下内容:

+----------------------------+
| Tables_in_blog_data        |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| blogsite_comment           |
| blogsite_post              |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
12 rows in set (0.01 sec)

在这些表中包括 blogsite_commentblogsite_post。这些是我们刚刚创建的模型。让我们验证它们是否包含我们定义的字段。

DESCRIBE blogsite_comment;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int          | NO   | PRI | NULL    | auto_increment |
| name       | varchar(42)  | NO   |     | NULL    |                |
| email      | varchar(75)  | NO   |     | NULL    |                |
| website    | varchar(200) | YES  |     | NULL    |                |
| content    | longtext     | NO   |     | NULL    |                |
| created_on | datetime(6)  | NO   |     | NULL    |                |
| post_id    | int          | NO   | MUL | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
DESCRIBE blogsite_post;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int          | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | NO   |     | NULL    |                |
| slug       | varchar(255) | NO   | UNI | NULL    |                |
| content    | longtext     | NO   |     | NULL    |                |
| created_on | datetime(6)  | NO   |     | NULL    |                |
| author     | longtext     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

我们已经验证了数据库表是否成功从我们的 Django 模型迁移中生成。

你可以使用 CTRL + D 退出 MySQL,当你准备离开 Python 环境时,可以运行 deactivate 命令:

deactivate

退出编程环境将使你回到终端命令提示符。

结论

在本教程中,我们成功为博客 Web 应用程序的基本功能添加了模型。你已经学会了如何编写 modelsmigrations 的工作原理以及将 Django models 转换为实际的 MySQL 数据库表的过程。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
SQL 数据库 索引
Django MTV - 模型层 - (专题)知识要点与实战案例
Django MTV - 模型层 - (专题)知识要点与实战案例
68 0
|
4月前
|
关系型数据库 MySQL 数据库
数据迁移脚本优化过程:从 MySQL 到 Django 模型表
在大规模的数据迁移过程中,性能问题往往是开发者面临的主要挑战之一。本文将分析一个数据迁移脚本的优化过程,展示如何从 MySQL 数据库迁移数据到 Django 模型表,并探讨优化前后的性能差异。
|
9天前
|
机器学习/深度学习 前端开发 网络架构
Django如何调用机器学习模型进行预测
Django如何调用机器学习模型进行预测
37 5
|
11天前
|
机器学习/深度学习 监控 数据挖掘
基于Django和百度飞桨模型的情感识别Web系统
基于Django和百度飞桨模型的情感识别Web系统
20 5
|
11天前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
15 4
|
8天前
|
存储 开发框架 JSON
【查漏补缺】Django模型字段类型及其应用
【查漏补缺】Django模型字段类型及其应用
7 0
|
2月前
|
机器学习/深度学习 前端开发 数据挖掘
基于Python Django的房价数据分析平台,包括大屏和后台数据管理,有线性、向量机、梯度提升树、bp神经网络等模型
本文介绍了一个基于Python Django框架开发的房价数据分析平台,该平台集成了多种机器学习模型,包括线性回归、SVM、GBDT和BP神经网络,用于房价预测和市场分析,同时提供了前端大屏展示和后台数据管理功能。
|
2月前
|
存储 数据库 开发者
Django Web架构:全面掌握Django模型字段(下)
Django Web架构:全面掌握Django模型字段(下)
52 2
|
2月前
|
API 数据库 开发者
【独家揭秘】Django ORM高手秘籍:如何玩转数据模型与数据库交互的艺术?
【8月更文挑战第31天】本文通过具体示例详细介绍了Django ORM的使用方法,包括数据模型设计与数据库操作的最佳实践。从创建应用和定义模型开始,逐步演示了查询、创建、更新和删除数据的全过程,并展示了关联查询与过滤的技巧,帮助开发者更高效地利用Django ORM构建和维护Web应用。通过这些基础概念和实践技巧,读者可以更好地掌握Django ORM,提升开发效率。
31 0
|
2月前
|
SQL Shell API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API