Django ForeignKey关系不起作用

时间:2018-08-15 10:06:54

标签: python django

由于外键的关系,应该有一个名为“ book_book_author(s)”的表。否则,我将无法访问Author.book_set。

class Author(models.Model):
    name=models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Book(models.Model):

    title = models.CharField(max_length=255)

    pub_date = models.DateField()

    publisher = models.CharField(max_length=255)

    language = models.CharField(max_length=255)

    print_length = models.DecimalField(max_digits=6, decimal_places=0)

    price = models.DecimalField(max_digits=10, decimal_places=2)

    authors=models.ForeignKey(Author, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

数据库:

mysql> show tables;
+-------------------------------+
| Tables_in_eshop               |
+-------------------------------+
| account_user                  |
| account_user_groups           |
| account_user_user_permissions |
| auth_group                    |
| auth_group_permissions        |
| auth_permission               |
| book_author                   |
| book_book                     |
| django_admin_log              |
| django_content_type           |
| django_migrations             |
| django_session                |
+-------------------------------+
12 rows in set (0.00 sec)

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

  

应该有一个名为'book_book_author(s)的表

:如果您编写一个ForeignKey关系,那么Django会将一个添加到名为book的{​​{1}}表中

现在,如果要获取给定author_id的{​​{1}}的列表,Django将构造一个查询:

Book

使用Author您要查询的SELECT book.* FROM book WHERE author_id = 123 的ID。它不会构造这种额外的表。这根本没有什么好处,因为它基本上会导致 same 查询(尽管在另一个表上并带有123,可以使它变得更少高效)。

为提高效率,Django默认会指示数据库还将在Author列上构造一个 index ,以便它可以轻松获取相关的JOIN表示author_id的ID。通常,这意味着在 O(log n)中,甚至在 O(1)中,都可以访问给定作者撰写的书籍列表。根据所使用的数据库技术,索引(或大量索引)将存储在数据库中,因此查找将非常快。

因此,您可以将Book视为要执行的查询,而不是表。

  

注意:对于Author,情况有所不同,在这种情况下,它将构造一个额外的表。这是因为通常,一列不包含任意数量的值(某些数据库可以包含,但仍然是不雅观的设计)。

您可以使用some_author.book_set获得ManyToManyField的书籍。此外,没有some_author(属于至少一位作者的书)。在这种情况下,这仅意味着所有本书,因为每本书都属于some_author.book_set.all()。如果Author.book_set可以为NULL,那么我们可以像Author一样进行过滤。

答案 1 :(得分:1)

基本上,当您定义外键时,不会创建新表,而是创建相应行的引用。

在您的情况下,您正在 Book 表上创建 Author 的引用。因此,您可以通过

访问作者的所有书籍
Book.objects.filter(author__id = 'authorid')