如何创建 Django 模型

介绍

在之前的教程中,),我们涵盖了如何创建一个MySQL数据库,如何创建和启动一个Django应用程序,以及如何将其连接到MySQL数据库。

在本教程中,我们将创建 Django 模型,这些模型将定义我们将存储的博客应用程序数据的领域和行为。

前提条件

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

如果你没有跟随这个系列,我们正在做以下假设:

  • 联合国 你安装了Django版本4或更高。
  • 联合国 您已经将您的 Django 应用程序连接到数据库 。 我们正在使用MySQL,通过遵循Django系列的第二部分),你们可以实现这种连接。 `
  • 联合国 您正在使用基于 Unix 的操作系统, 最好是 Ubuntu 22.04 云端服务器, 因为这是我们测试过的系统 。 如果您想在类似环境中设立Django,请参考我们的教程:)。 `

由于本教程主要涉及Django模型,即使您有稍微不同的设置,您也可能能够跟进。

第1步:创建Django应用程序

为了符合Django的模块化理念,我们将在我们的项目中创建一个Django应用程序,其中包含创建博客网站所需的所有文件。

每当我们开始在Python和Django工作时,我们应该激活我们的Python虚拟环境并进入我们的应用程序的根目录。

1cd ~/my_blog_app
2. env/bin/activate
3cd blog

从那里,让我们运行这个命令:

1python manage.py startapp blogsite

这将创建我们的应用程序以及一个博客网站目录。

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

 1my_blog_app/
 2└── blog
 3    ├── blog
 4    │   ├── __init__.py
 5    │   ├── __pycache__
 6    │   │   ├── __init__.cpython-38.pyc
 7    │   │   ├── settings.cpython-38.pyc
 8    │   │   ├── urls.cpython-38.pyc
 9    │   │   └── wsgi.cpython-38.pyc
10    │   ├── asgi.py
11    │   ├── settings.py
12    │   ├── urls.py
13    │   └── wsgi.py
14    ├── blogsite
15    │   ├── __init__.py
16    │   ├── admin.py
17    │   ├── apps.py
18    │   ├── migrations
19    │   │   └── __init__.py
20    │   ├── models.py
21    │   ├── tests.py
22    │   └── views.py
23    └── manage.py

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

步骤 2 - 添加帖子模型

首先我们需要打开和编辑 models.py 文件,以便它包含生成 Post 模型的代码。

  • 标题 - 博客文章的标题. * slug - 存储和生成有效的网页 URL. * 内容 - 博客文章的文本内容. * created_on - 该帖子创建的日期. * 作者 - 撰写该帖子的个人。

现在,转到包含models.py文件的目录。

1cd ~/my_blog_app/blog/blogsite

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

1cat models.py

该文件应该包含以下代码,该代码导入模型,以及描述该models.py文件中的内容的评论。

1[label models.py]
2from django.db import models
3
4# Create your models here.

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

1nano models.py

在此文件中,已经添加了导入模型API的代码,我们可以继续删除下面的评论,然后我们将导入slugify来生成从字符串的 slugs,Django的用户来验证,并从django.urls导入反向,以便我们更灵活地创建URL。

1[label models.py]
2from django.db import models
3from django.template.defaultfilters import slugify
4from django.contrib.auth.models import User
5from django.urls import reverse

然后,在我们将称之为邮件的模型类上添加类方法,下列数据库领域为标题,slug,内容,created_on作者

1[label models.py]
2...
3class Post(models.Model):
4    title = models.CharField(max_length=255)
5    slug = models.SlugField(unique=True, max_length=255)
6    content = models.TextField()
7    created_on = models.DateTimeField(auto_now_add=True)
8    author = models.TextField()

接下来,我们将添加功能来生成URL和功能来保存帖子,这是至关重要的,因为这会创建一个独特的链接来匹配我们的独特帖子。

1[label models.py]
2...
3    def get_absolute_url(self):
4        return reverse('blog_post_detail', args=[self.slug])
5
6    def save(self, *args, **kwargs):
7        if not self.slug:
8            self.slug = slugify(self.title)
9        super(Post, self).save(*args, **kwargs)

现在,我们需要告诉模型如何排序帖子,并显示在网页上。为此的逻辑将被添加到嵌入的内部Meta类中。

1[label models.py]
2...
3    class Meta:
4        ordering = ['created_on']
5
6        def __unicode__(self):
7            return self.title

最后,我们会将评论模型添加到这个文件中,这涉及在其签名中添加另一个名为评论的类,并定义了以下数据库字段:

  • 「名稱」 - 發表評論的人的名稱. * 「電子郵件」 - 發表評論的人的電子郵件地址. * 「文本」 - 評論本身的文本. * 「郵件」 - 評論所使用的帖子. * 「Created_on」 - 評論所建立的時間。
1[label models.py]
2...
3class Comment(models.Model):
4    name = models.CharField(max_length=42)
5    email = models.EmailField(max_length=75)
6    website = models.URLField(max_length=200, null=True, blank=True)
7    content = models.TextField()
8    post = models.ForeignKey(Post, on_delete=models.CASCADE)
9    created_on = models.DateTimeField(auto_now_add=True)

在此时,models.py 将完成,请确保您的models.py 文件符合以下内容:

 1[label models.py]
 2from django.db import models
 3from django.template.defaultfilters import slugify
 4from django.contrib.auth.models import User
 5from django.urls import reverse
 6
 7class Post(models.Model):
 8    title = models.CharField(max_length=255)
 9    slug = models.SlugField(unique=True, max_length=255)
10    content = models.TextField()
11    created_on = models.DateTimeField(auto_now_add=True)
12    author = models.TextField()
13
14    def get_absolute_url(self):
15        return reverse('blog_post_detail', args=[self.slug])
16
17    def save(self, *args, **kwargs):
18        if not self.slug:
19            self.slug = slugify(self.title)
20        super(Post, self).save(*args, **kwargs)
21
22    class Meta:
23        ordering = ['created_on']
24
25        def __unicode__(self):
26            return self.title
27
28class Comment(models.Model):
29    name = models.CharField(max_length=42)
30    email = models.EmailField(max_length=75)
31    website = models.URLField(max_length=200, null=True, blank=True)
32    content = models.TextField()
33    post = models.ForeignKey(Post, on_delete=models.CASCADE)
34    created_on = models.DateTimeField(auto_now_add=True)

如果您正在使用 nano,您可以通过键入CTRLX,然后Y,然后ENTER来做到这一点。

随着models.py文件的设置,我们可以继续更新我们的settings.py文件。

第3步:更新设置

现在我们已将模型添加到我们的应用程序中,我们必须告知我们的项目我们刚刚添加的blogsite应用程序的存在,我们通过将其添加到Settings.py中的INSTALLED_APPS部分。

导航到您的settings.py居住的目录。

1cd ~/my_blog_app/blog/blog

从这里,打开你的settings.py文件,例如 nano。

1nano settings.py

打开文件时,将您的blogsite应用程序添加到文件的INSTALLED_APPS部分,如下所示。

 1[label settings.py]
 2# Application definition
 3INSTALLED_APPS = [
 4    'blogsite',
 5    'django.contrib.admin',
 6    'django.contrib.auth',
 7    'django.contrib.contenttypes',
 8    'django.contrib.sessions',
 9    'django.contrib.messages',
10    'django.contrib.staticfiles',
11]

通过添加blogsite应用程序,您可以保存和退出文件。

此时此刻,我们已准备好继续实施这些变化。

步骤4 - 进行迁移

随着我们的模型发布评论的添加,下一步是应用这些更改,以便我们的MySQL数据库架构识别它们并创建必要的表。

首先,我们必须将我们的模型更改包装到单个迁移文件中,使用命令makemigrations

现在,如果你导航到~/my_blog_app/blog/blogsite/migrations并运行ls,你会注意到只有一个__init__.py文件。

使用CD更改博客目录,如下:

1cd ~/my_blog_app/blog

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

1python manage.py makemigrations

您应该在您的终端窗口中收到以下输出:

1[secondary_label Output]
2Migrations for 'blogsite':
3  blogsite/migrations/0001_initial.py
4    - Create model Post
5    - Create model Comment

记住,当我们导航到/~/my_blog_app/blog/blogsite/migrations时,它只有__init__.py文件?如果我们现在cd返回该目录,我们会注意到已经添加了两个项目:__pycache__0001_initial.py

从它所在的目录中运行less 0001_initial.py,如果你想读取文件中的内容。

现在导航到 ~/my_blog_app/blog:

1cd ~/my_blog_app/blog

由于我们已经创建了一个迁移文件,我们必须使用迁移命令将这些文件描述的更改应用到数据库中,但首先让我们使用显示迁移命令来检查目前存在的迁移。

1python manage.py showmigrations
 1[secondary_label Output]
 2admin
 3 [X] 0001_initial
 4 [X] 0002_logentry_remove_auto_add
 5 [X] 0003_logentry_add_action_flag_choices
 6auth
 7 [X] 0001_initial
 8 [X] 0002_alter_permission_name_max_length
 9 [X] 0003_alter_user_email_max_length
10 [X] 0004_alter_user_username_opts
11 [X] 0005_alter_user_last_login_null
12 [X] 0006_require_contenttypes_0002
13 [X] 0007_alter_validators_add_error_messages
14 [X] 0008_alter_user_username_max_length
15 [X] 0009_alter_user_last_name_max_length
16 [X] 0010_alter_group_name_max_length
17 [X] 0011_update_proxy_permissions
18blogsite
19 [ ] 0001_initial
20contenttypes
21 [X] 0001_initial
22 [X] 0002_remove_content_type_name
23sessions
24 [X] 0001_initial

您会注意到所有迁移都被检查,除了我们刚刚使用模型帖子评论创建的0001_初始的迁移。

现在,让我们检查哪个SQL语句将执行,一旦我们完成迁移,使用以下命令:它将迁移和迁移的标题作为论点:

1python manage.py sqlmigrate blogsite 0001_initial

下面揭示的是幕后正在进行的实际SQL查询。

 1[secondary_label Output]
 2--
 3-- Create model Post
 4--
 5CREATE 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);
 6--
 7-- Create model Comment
 8--
 9CREATE 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);
10ALTER TABLE `blogsite_comment` ADD CONSTRAINT `blogsite_comment_post_id_de248bfe_fk_blogsite_post_id` FOREIGN KEY (`post_id`) REFERENCES `blogsite_post` (`id`);

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

1python manage.py migrate

我们将获得以下产出:

1[secondary_label Output]
2Operations to perform:
3  Apply all migrations: admin, auth, blogsite, contenttypes, sessions
4Running migrations:
5  Applying blogsite.0001_initial... OK

您现在已经成功地应用了您的迁移。

重要的是要记住, Django 迁移与 MySQL 作为您的后端有三个警告,正如 Django 文档中所述。

  • 围绕计划改建业务的交易缺乏支持。 换句话说,如果移民无法成功应用,你必须手动解开你所做的改变,以便尝试另一次移民。 在移徙失败之前,不可能倒退到更早的时候。
  • 联合国 对于大多数的Schema修改操作,MySQL会完全重写表格. 在最坏的情况下,时间复杂度会与表格中的行数成正比来添加或去除列. 根据Django文件,速度可能为每百万行1分钟。
  • 在MySQL中,列,表和索引的名称长度有小的限制. 所有栏和索引盖的合并大小也有限制。 虽然其他一些后端可以支持在Django所设定的更高限度,但同样的指数将无法在MySQL后端到位的情况下创建. .

对于您考虑与 Django 一起使用的每个数据库,请确保衡量每个数据库的优点和缺点。

第5步:验证数据库计划

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

我們將使用我們在 [上一本教程] 中創建的 djangouser(https://andsky.com/tech/tutorials/how-to-create-a-django-app-and-connect-it-to-a-database# step-5-%E2%80%94-create-the-database)。

1mysql blog_data -u djangouser

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

1USE blog_data;

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

1SHOW TABLES;

此 SQL 查询应该显示如下:

 1[secondary_label Output]
 2+----------------------------+
 3| Tables_in_blog_data        |
 4+----------------------------+
 5| auth_group                 |
 6| auth_group_permissions     |
 7| auth_permission            |
 8| auth_user                  |
 9| auth_user_groups           |
10| auth_user_user_permissions |
11| blogsite_comment           |
12| blogsite_post              |
13| django_admin_log           |
14| django_content_type        |
15| django_migrations          |
16| django_session             |
17+----------------------------+
1812 rows in set (0.01 sec)

表中包括「blogsite_comment」和「blogsite_post」。 这些是我们自己刚刚制作的模型,让我们验证它们是否包含我们定义的字段。

1DESCRIBE blogsite_comment;
 1[secondary_label Output]
 2+------------+--------------+------+-----+---------+----------------+
 3| Field      | Type         | Null | Key | Default | Extra          |
 4+------------+--------------+------+-----+---------+----------------+
 5| id         | int          | NO   | PRI | NULL    | auto_increment |
 6| name       | varchar(42)  | NO   |     | NULL    |                |
 7| email      | varchar(75)  | NO   |     | NULL    |                |
 8| website    | varchar(200) | YES  |     | NULL    |                |
 9| content    | longtext     | NO   |     | NULL    |                |
10| created_on | datetime(6)  | NO   |     | NULL    |                |
11| post_id    | int          | NO   | MUL | NULL    |                |
12+------------+--------------+------+-----+---------+----------------+
137 rows in set (0.00 sec)
1DESCRIBE blogsite_post;
 1[secondary_label Output]
 2+------------+--------------+------+-----+---------+----------------+
 3| Field      | Type         | Null | Key | Default | Extra          |
 4+------------+--------------+------+-----+---------+----------------+
 5| id         | int          | NO   | PRI | NULL    | auto_increment |
 6| title      | varchar(255) | NO   |     | NULL    |                |
 7| slug       | varchar(255) | NO   | UNI | NULL    |                |
 8| content    | longtext     | NO   |     | NULL    |                |
 9| created_on | datetime(6)  | NO   |     | NULL    |                |
10| author     | longtext     | NO   |     | NULL    |                |
11+------------+--------------+------+-----+---------+----------------+
126 rows in set (0.00 sec)

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

您可以用CTRL +D关闭MySQL,当您准备离开Python环境时,您可以运行禁用命令:

1deactivate

停用您的编程环境将使您回到终端命令提示。

结论

在本教程中,我们已经成功地在博客Web应用程序中添加了基本功能的模型,您已经学会了如何编码模型,如何迁移工作,以及将Django模型翻译成实际的MySQL数据库表的过程。

Published At
Categories with 技术
comments powered by Disqus