Reputation: 97
My models.py
:
class Author(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField(
"Book", related_name="books", blank=True
)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ManyToManyField(Author)
In Django admin
I first created an instance of Author
, without assigning him any Book
:
Then I created a new Book
and assigned Leo Tolstoy as theAuthor
:
In Django shell, I am able to access the Book
's Author
:
>>> Book.objects.filter(title="War and Peace").first().author.first()
<Author: Leo Tolstoy>
But I'm unable to access the Author
's Books
:
>>> Author.objects.filter(name="Leo Tolstoy").first().books.all()
<QuerySet []>
The book isn't assigned in the Admin
view either:
I would like to access the Author
's Books
as well as for the Books
to show in the Author
's Admin
view.
Upvotes: 0
Views: 300
Reputation: 364
I suggest you do this:
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ManyToManyField(Author, related_name="books",blank=True)
You need one ManyToManyField
, then django will create two associative tables between the book
and author
tables. Changes to one table will not affect the other. You can see in the django documentation about many to many relationships. I have removed your books
field in my answer because you have created an instance of your Author
but you did not assign his 'book' and you have created a Book
instance with giving title
and author
in your Book
model. So so that any of your data won't be deleted. I also added related_name
to your author
field in your Book
model because when you try to get the books related to the author (for example "Loe Tolstoy") you can get by this:
Author.objects.get(name="Leo Tolstoy").books.all()
Upvotes: 1
Reputation: 468
You only need one ManyToManyField
. You should also pass "books"
as the related_name
on Book.authors
as this is the name Django will use for the many-to-many manager attribute it automatically adds to Author
instances.
See the example in the Django docs for more info.
When a ManyToManyField
is created on both sides of a relation, Django is creating two associative tables between the book and author tables under the hood. Changes to one table don't affect the other.
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(
Author, related_name="books", blank=True
)
Upvotes: 2