views:

1089

answers:

2

I have the following models:

class Author(models.Model):
  author_name = models.CharField()

class Book(models.Model):
  book_name = models.CharField()

class AuthorBook(models.Model):
  author_id = models.ForeignKeyField(Author)
  book_id = models.ForeignKeyField(Book)

With that being said, I'm trying to emulate this query using the Django ORM (select all of the books written by a specific author, noting that Authors can have many books and Books can have many Authors):

SELECT book_name 
FROM authorbook, book
WHERE authorbook.author_id = 1
AND authorbook.book_id = book.id

I've read this FAQ page on the Django website, but before I modify my model structure and remove AuthorBook, I was curious if I could emulate that query using the current structure.

+5  A: 

You should be able to do:

books = Book.objects.filter(authorbook__author_id=1)

to get a QuerySet of Book objects matching your author_id restriction.

The nice thing about Django is you can cook this up and play around with it in the shell. You may also find http://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships to be useful.

Emil
Argh. Thanks -- brain only half working today. :)
Huuuze
webjunkie's response seems better. Just learning Django myself.
Emil
In general, there's no reason to explicitly mention the id field in the ORM. Assuming you have an Author instance, you'd want Book.objects.filter(authorbook__author=author). But a ManyToManyField is the way to go, of course.
Carl Meyer
Another example lookup by author name: Book.objects.filter(authors__author_name__endswith=u' Klein') assuming you're using webjunkie's ManyToMany based schema.
akaihola
+4  A: 

"AuthorBook" seems not correctly modeled.

You should use a ManyToManyField:

class Book(models.Model):
  name = models.CharField()
  authors = models.ManyToManyField(Author)

Then you can do:

books = Book.objects.filter(authors__id=1)
webjunkie
+1 for suggesting ManyToManyField (that's the Django way), -1 for not knowing that that's how it's done "under the hood".
Javier
Of course do m2m relationships use intermediary tables. Still it is not correctly modeled using Django in this case. There's no point in having me making obvious that I know how it's working under the hood.
webjunkie