Reputation: 2660
I have two classes: Author and Book. I want class Authors to have an attribute that contains all books written by the said author, as referenced to as foreign key in the class Books. The method I did does not appear to be working, which I assume is because when the database is being created in migrations, no Books objects exist yet. Or so I believe, I'm pretty new at django.
class Author(models.Model):
AuthorName = models.CharField(max_length=255, unique=True)
books = Book.objects.get(pk=object_instance.pk)
class Book(models.Model):
BookName = models.CharField(max_length=255)
Author = models.ForeignKey('Author')
The error message I get is:
NameError: name 'Book' is not defined
Which I get, is because I'm referencing to another class without actually having and instance of that class. I just can't figure out a proper way to do this.
EDIT: I reformatted it to be like this:
class Author(models.Model):
AuthorName = models.CharField(max_length=255, unique=True)
books = author.book_set.all()
class Book(models.Model):
BookName = models.CharField(max_length=255)
Author = models.ForeignKey('Author')
which yields error:
NameError: name 'author' is not defined
Maybe I should just query for the datapoints I need later on in views as opposed to creating own field for them in models though..
EDIT 2: solution from answers:
So my mistake all along was to try to add the "books" field in the author table. I guess there's no way to do this then. I can get that method to work in views so I guess this is sort of solved, although not in the way I was originally planning to do it.
doing
class Author(models.Model):
AuthorName = models.CharField(max_length=255, unique=True)
class Book(models.Model):
BookName = models.CharField(max_length=255)
Author = models.ForeignKey('Author')
and then later doing this in views:
author = Author.objects.get(pk=1)
books = author.book_get.all()
yields the wanted result (which I sort of knew beforehand, but I was trying to implement a books field in the models, which, if i correctly understood, is not possible at least not with this method).
another solution:
class Author(models.Model):
AuthorName = models.CharField(max_length=255, unique=True)
class Book(models.Model):
BookName = models.CharField(max_length=255)
Author = models.ForeignKey(Author, related_name = "books")
Upvotes: 28
Views: 61586
Reputation: 476
You did something weird in line:
books = Book.objects.get(pk=object_instance.pk)
Just delete it. You will be able to use author.book_set
. You can also use related_name
parameter of ForeignKey
.
See the Django docs: https://docs.djangoproject.com/en/4.0/ref/models/fields/#foreignkey
Upvotes: 4
Reputation: 1090
Just add related_name
to ForeignKey and you will be able to get all books made by an author.
For example:
class Book(models.Model):
...
author = models.ForeignKey('Author', related_name='books')
...
and later...
author = Author.objects.get(pk=1)
books = author.books.all()
Upvotes: 17
Reputation: 5475
You don't need to create a separate field in Authors
model
class Author(models.Model):
AuthorName = models.CharField(max_length=255, unique=True)
class Book(models.Model):
BookName = models.CharField(max_length=255)
Author = models.ForeignKey('Author')
You can get all books of a particular author like:
author = Author.objects.get(id=1)
books = author.book_set.all()
Learn more about backward relationships here
Upvotes: 41