介绍
在之前的教程中,),我们涵盖了如何创建一个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,您可以通过键入CTRL
和X
,然后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
数据库表的过程。