繁体   English   中英

Django ForeignKey关系不起作用

[英]Django ForeignKey relationship is not working

由于外键关系,应该有一个名为“ 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)

如何解决此问题?

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

:如果您编写了ForeignKey关系,那么Django将在您的book表中添加一 author_id

现在,如果要获取给定AuthorBook列表,则Django将构造一个查询,如下所示:

SELECT book.*
FROM book
WHERE author_id = 123

123是您要查询的Author的ID。 建立这样的额外的表。 这不会是在所有人都有益的,因为这将基本上导致相同的查询(尽管其它表,并与JOIN ,它可以使效率较低 )。

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

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

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

您可以使用some_author.book_set.all()获得some_author的书。 此外,没有Author.book_set (属于至少一位作者的书)。 在这种情况下,这仅意味着所有书籍,因为每本书都属于一个Author 如果ForeignKey为NULL,则可以像Books.objects.filter(author__isnull=False)那样Books.objects.filter(author__isnull=False)过滤。

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

在您的情况下,您要在Book表上创建Author的引用。 因此,您可以通过以下方式访问作者的所有书籍:

Book.objects.filter(author__id = 'authorid')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM