django创建模型失败_如何创建Django模型

本文是Django开发系列的一部分,讲解如何在遇到困难时创建Django模型。内容涵盖创建Django应用程序、定义Posts模型、更新设置、进行数据库迁移以及验证数据库架构。适合已具备Django和数据库连接基础的读者。

django创建模型失败

介绍 (Introduction)

In the previous tutorial, “How To Create a Django App and Connect it to a Database,” we covered how to create a MySQL database, how to create and start a Django application, and how to connect it to a MySQL database.

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

In this tutorial, we will create the Django models that define the fields and behaviors of the Blog application data that we will be storing. These models map the data from your Django application to the database. It’s what Django uses to generate the database tables via their object relational mapping (ORM) API, referred to as “models.”

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

先决条件 (Prerequisites)

This tutorial is part of the Django Development series and is a continuation of that series.

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

If you have not followed along with this series, we are making the following assumptions:

如果您未遵循本系列文章,我们将进行以下假设:

As this tutorial is largely dealing with Django models, you may be able to follow along even if you have a somewhat different setup.

由于本教程主要涉及Django模型,因此即使设置有所不同,您也可以继续学习。

第1步-创建Django应用程序 (Step 1 — Create Django Application)

To be consistent with the Django philosophy of modularity, we will create a Django app within our project that contains all of the files necessary for creating the blog website.

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

Whenever we begin doing work in Python and Django, we should activate our Python virtual environment and move into our app’s root directory. If you followed along with the series, you can achieve this by typing the following.

每当我们开始在Python和Django中进行工作时,都应激活Python虚拟环境并移至应用程序的根目录。 如果按照该系列进行学习,则可以通过键入以下内容来实现。

  • cd ~/my_blog_app

    cd〜/ my_blog_app
  • . env/bin/activate

    。 env / bin / activate
  • cd blog

    cd博客

From there, let’s run this command:

从那里开始,运行以下命令:

  • python manage.py startapp blogsite

    python manage.py startapp博客网站

This will create our app along with a blogsite directory.

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

At this point in the tutorial series, you’ll have the following directory structure for your project:

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

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

The file we will focus on for this tutorial, will be the models.py file, which is in the blogsite directory.

在本教程中,我们将重点关注的文件是在blogsite目录中的models.py文件。

第2步-添加帖子模型 (Step 2 — Add the Posts Model)

First we need to open and edit the models.py file so that it contains the code for generating a Post model. A Post model contains the following database fields:

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

  • title — The title of the blog post.

    title —博客文章的标题。

  • slug — Where valid URLs are stored and generated for web pages.

    slug存储和生成网页的有效URL的位置。

  • content — The textual content of the blog post.

    content -博客文章的文本内容。

  • created_on — The date on which the post was created.

    created_on创建帖子的日期。

  • author — The person who has written the post.

    author —撰写帖子的人。

Now, move into the directory where the models.py file is contained.

现在,移至包含models.py文件的目录。

  • cd ~/my_blog_app/blog/blogsite

    cd〜/ my_blog_app / blog / blogsite

Use the cat command to show the contents of the file in your terminal.

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

  • cat models.py

    猫模型

The file should have the following code, which imports models, along with a comment describing what is to be placed into this models.py file.

该文件应具有以下代码,这些代码可以导入模型,并带有描述要放入此models.py文件的注释。

models.py
models.py
from django.db import models

# Create your models here.

Using your favorite text editor, add the following code to the models.py file. We’ll use nano as our text editor, but you are welcome to use whatever you prefer.

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

  • nano models.py

    纳米模型

Within this file, the code to import the models API is already added, we can go ahead and delete the comment that follows. Then we’ll import slugify for generating slugs from strings, Django’s User for authentication, and reverse from django.urls to give us greater flexibility with creating URLs.

在此文件中,已经添加了导入模型API的代码,我们可以继续删除下面的注释。 然后,我们将导入slugify以便从字符串生成slug,使用Django的User进行身份验证,并从django.urls reverse进行django.urls从而为我们提供了创建URL的更大灵活性。

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

Then, add the class method on the model class we will be calling Post, with the following database fields, title, slug, content, created_on and author. Add these below your import statements.

然后,在将要调用Post的模型类上添加类方法,并使用以下数据库字段: titleslugcontentcreated_onauthor 。 将这些添加到您的导入语句下面。

models.py
models.py
...
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()

Next, we will add functionality for the generation of the URL and the function for saving the post. This is crucial, because this creates a unique link to match our unique post.

接下来,我们将添加用于生成URL的功能和用于保存帖子的功能。 这很关键,因为这会创建一个唯一的链接来匹配我们的独特帖子。

models.py
models.py
...
    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)

Now, we need to tell the model how the posts should be ordered, and displayed on the web page. The logic for this will be added to a nested inner Meta class. The Meta class generally contains other important model logic that isn’t related to database field definition.

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

models.py
models.py
...
    class Meta:
        ordering = ['created_on']

        def __unicode__(self):
            return self.title

Finally, we will add the Comment model to this file. This involves adding another class named Comment with models.Models in its signature and the following database fields defined:

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

  • name — The name of the person posting the comment.

    name -发表评论的人的名字。

  • email — The email address of the person posting the comment.

    email -发表评论的人的电子邮件地址。

  • text — The text of the comment itself.

    text -评论本身的文字。

  • post — The post with which the comment was made.

    post —发表评论的帖子。

  • created_on — The time the comment was created.

    created_on —创建评论的时间。

models.py
models.py
...
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)

At this point models.py will be complete. Ensure that your models.py file matches the following:

至此, models.py将完成。 确保您的models.py文件符合以下条件:

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)

Be sure to save and close the file. If you’re using nano, you can do so by typing CTRL and X, then Y, then ENTER.

确保保存并关闭文件。 如果您使用的是nano,则可以通过按CTRLX ,然后按Y ,然后按ENTER

With the models.py file set up, we can go on to update our settings.py file.

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

步骤3 —更新设置 (Step 3 — Update Settings)

Now that we’ve added models to our application, we must inform our project of the existence of the blogsite app that we’ve just added. We do this by adding it to the INSTALLED_APPS section in settings.py.

现在,我们已经向应用程序中添加了模型,我们必须通知我们的项目有关刚刚添加的blogsite应用程序的存在。 为此,我们将其添加到settings.pyINSTALLED_APPS部分。

Navigate to the directory where your settings.py lives.

导航到settings.py所在的目录。

  • cd ~/my_blog_app/blog/blog

    cd〜/ my_blog_app / blog / blog

From here, open up your settings.py file, with nano, for instance.

例如,从此处打开您的settings.py文件,例如nano。

  • nano settings.py

    纳米settings.py

With the file open, add your blogsite app to the INSTALLED_APPS section of the file, as indicated below.

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

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

With the blogsite app added, you can save and exit the file.

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

At this point, we are ready to move on to apply these changes.

至此,我们准备继续应用这些更改。

第4步-进行迁移 (Step 4 — Make Migrations)

With our models Post and Comment added, the next step is to apply these changes so that our MySQL database schema recognizes them and creates the necessary tables.

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

First, we must package up our model changes into individual migration files using the command makemigrations. These files are similar to that of commits in a version control system like Git.

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

Now, if you navigate to ~/my_blog_app/blog/blogsite/migrations and run ls, you’ll notice that there is only an __init__.py file. This will change once we add the migrations.

现在,如果导航到~/my_blog_app/blog/blogsite/migrations并运行ls ,则会注意到只有__init__.py文件。 一旦添加迁移,这种情况就会改变。

Change to the blog directory using cd, like so:

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

  • cd ~/my_blog_app/blog

    cd〜/ my_blog_app / blog

Then run the makemigrations command on manage.py.

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

  • python manage.py makemigrations

    python manage.py makemigrations

You should then receive the following output in your terminal window:

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


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

Remember, when we navigated to /~/my_blog_app/blog/blogsite/migrations and it only had the __init__.py file? If we now cd back to that directory we’ll notice that two items have been added: __pycache__ and 0001_initial.py. The 0001_initial.py file was automatically generated when you ran makemigrations. A similar file will be generated every time you run makemigrations.

还记得我们导航到/~/my_blog_app/blog/blogsite/migrations ,它只有__init__.py文件吗? 如果我们现在cd回到那个目录,我们会发现,两个项目已添加: __pycache__0001_initial.py 。 运行makemigrations时,将自动生成0001_initial.py文件。 每次运行makemigrations都会生成一个类似的文件。

Run less 0001_initial.py from the directory it’s in if you’d like to read over what the file contains.

如果要阅读文件包含的内容, less 0001_initial.py从其所在的目录中运行less 0001_initial.py

Now navigate to ~/my_blog_app/blog:

现在导航到~/my_blog_app/blog

  • cd ~/my_blog_app/blog

    cd〜/ my_blog_app / blog

Since we have made a migration file, we must apply the changes these files describe to the database using the command migrate. But first let’s check which migrations currently exist, using the showmigrations command.

既然我们已经做了一个迁移文件,我们必须将这些文件描述了使用命令数据库的更改migrate 。 但是首先让我们使用showmigrations命令检查当前存在哪些迁移。

  • python manage.py showmigrations

    python manage.py showmigrations

   
Output
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

You’ll notice that all migrations are checked except for the one for 0001_initial which we just created with the models Post and Comment.

您会注意到,除了刚才使用PostComment模型创建的0001_initial迁移之外,所有迁移都已检查。

Now let’s check which SQL statements will be executed once we make the migrations, using the following command. It takes in the migration and the migration’s title as an argument:

现在,使用以下命令检查在进行迁移后将执行哪些SQL语句。 它以迁移和迁移的标题作为参数:

  • python manage.py sqlmigrate blogsite 0001_initial

    python manage.py sqlmigrate博客网站0001_initial

Revealed below is the actual SQL query being made behind the scenes.

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


   
Output
-- -- 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`);

Let’s now perform the migrations so that they get applied to our MySQL database.

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

  • python manage.py migrate

    python manage.py迁移

We will receive the following output:

我们将收到以下输出:


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

You have now successfully applied your migrations.

现在,您已成功应用了迁移。

It is important to keep in mind that there are 3 caveats to Django migrations with MySQL as your backend, as stated in the Django documentation.

重要的是要记住,如Django文档中所述,以MySQL作为后端对Django迁移有3个警告。

  • Lack of support for transactions around schema alteration operations. In other words, if a migration fails to apply successfully, you will have to manually unpick the changes you’ve made in order to attempt another migration. It is not possible to rollback, to an earlier point, before any changes were made in the failed migration.

    缺乏对围绕模式更改操作的事务的支持。 换句话说,如果迁移无法成功应用,则您必须手动取消选择所做的更改才能尝试进行另一次迁移。 在失败的迁移中进行任何更改之前,不可能回滚到更早的时间。
  • For most schema alteration operations, MySQL will fully rewrite tables. In the worst case, the time complexity will be proportional to the number of rows in the table to add or remove columns. According to the Django documentation, this could be as slow as one minute per million rows.

    对于大多数模式更改操作,MySQL将完全重写表。 在最坏的情况下,时间复杂度将与表中添加或删除列的行数成比例。 根据Django文档,这可能慢至每百万行一分钟。
  • In MySQL, there are small limits on name lengths for columns, tables and indices. There is also a limit on the combined size of all columns and index covers. While some other backends can support higher limits created in Django, the same indices will fail to be created with a MySQL backend in place.

    在MySQL中,列,表和索引的名称长度有很小的限制。 所有列和索引封面的组合大小也有限制。 尽管其他一些后端可以支持在Django中创建的更高限制,但是在使用MySQL后端的情况下无法创建相同的索引。

For each database you consider for use with Django, be sure to weigh the advantages and disadvantages of each.

对于您考虑与Django一起使用的每个数据库,请务必权衡每个数据库的优缺点。

步骤5 —验证数据库架构 (Step 5 — Verify Database Schema)

With migrations complete, we should verify the successful generation of the MySQL tables that we’ve created via our Django models.

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

To do this, run the following command in the terminal to log into MySQL. We’ll use the djangouser we created in the previous tutorial.

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

  • mysql blog_data -u djangouser

    mysql blog_data -u djangouser

Now, select our database blog_data. If you don’t know the database you are using, you can show all databases withSHOW DATABASES; in SQL.

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

  • USE blog_data;

    使用blog_data;

Then type the following command to view the tables.

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

  • SHOW TABLES;

    显示表;

This SQL query should reveal the following:

此SQL查询应显示以下内容:


   
Output
+----------------------------+ | 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)

Among the tables are blogsite_comment and blogsite_post. These are the models that we’ve just made ourselves. Let’s validate that they contain the fields we’ve defined.

这些表中有blogsite_commentblogsite_post 。 这些是我们自己制作的模型。 让我们验证它们是否包含我们定义的字段。

  • DESCRIBE blogsite_comment;

    DESCRIBE blogsite_comment;

   
Output
+------------+--------------+------+-----+---------+----------------+ | 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;

    DESCRIBE blogsite_post;

   
Output
+------------+--------------+------+-----+---------+----------------+ | 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)

We have verified that the database tables were successfully generated from our Django model migrations.

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

You can close out of MySQL with CTRL + D and when you are ready to leave your Python environment, you can run the deactivate command:

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

  • deactivate

    停用

Deactivating your programming environment will put you back to the terminal command prompt.

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

结论 (Conclusion)

In this tutorial, we’ve successfully added models for basic functionality in a blog web application. You’ve learned how to code models, how migrations work and the process of translating Django models to actual MySQL database tables.

在本教程中,我们已在博客Web应用程序中成功添加了基本功能模型。 您已经了解了如何对models进行编码,如何进行migrations以及将Django models转换为实际的MySQL数据库表的过程。

翻译自: https://www.digitalocean.com/community/tutorials/how-to-create-django-models

django创建模型失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值