简体   繁体   中英

Django ForeignKey relationship is not working

There should be a table called like 'book_book_author(s)' due to the Foreign Key relationships. Otherwise I cannot access the 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

The database:

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)

How can I fix this issue?

There should be a table called like 'book_book_author(s)

No : if you write a ForeignKey relation, then Django will add a column to your book table named author_id .

Now if you want to obtain the list of Book s for a given Author , Django will construct a query like:

SELECT book.*
FROM book
WHERE author_id = 123

with 123 the id of the Author you are querying. It does not construct such extra table. This would not be beneficial at all, since it would basically result in the same query (although on another table, and with a JOIN , which can make it less efficient).

To make it more efficient, Django will by default instruct the database will also construct an index on the author_id column, such that it can easily obtain the relevant Book s for an Author id. Usually this means that in O(log n) , or even O(1) one can get access to the list of books that are written by a given author. Depending on the database technology used, the index (or a large amount) will be stored in the database, and thus lookups will be quite fast.

You can thus see the some_author.book_set as a query you are going to execute, not a table.

Note : for ManyToManyField s the situation is different, in that case it will construct an extra table. This is because usually, a column does not contain an arbitrary amount of values (well some databases can, but still it is inelegant design).

You can obtain the books of some_author with some_author.book_set.all() . Furthermore there is no Author.book_set (books that belong to at least one author). In this case this would mean simply all books, since every book belongs to an Author . If the ForeignKey was NULL-able, then we could filter like Books.objects.filter(author__isnull=False) .

Basically when you define a foreign key, then a new table is not created, rather the a reference of the corresponding row is made.

In your case you are creating a reference of Author on the Book table. Hence you can access all the books of an author by

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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