2009-02-10 3 views
5

Je les modèles suivants:Comment utiliser l'ORM de Django pour interroger cet exemple many-to-many?

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) 

Cela étant dit, je suis en train d'imiter cette requête en utilisant Django ORM (sélectionner tous les livres écrits par un auteur spécifique, en notant que les auteurs peuvent avoir de nombreux livres et livres peuvent avoir de nombreux auteurs):

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

J'ai lu this FAQ page sur le site Django, mais avant que je modifie ma structure de modèle et supprimer AuthorBook, j'étais curieux de savoir si je pouvais imiter cette requête en utilisant la structure actuelle .

Répondre

14

Vous devriez être en mesure de le faire:

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

pour obtenir un objets QuerySet du livre correspondant à votre restriction author_id. La bonne chose à propos de Django est que vous pouvez le cuisiner et le jouer dans le shell. Vous pouvez également trouver http://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships pour être utile.

+0

Argh. Merci - le cerveau ne fonctionne qu'à moitié aujourd'hui. :) – Huuuze

+0

La réponse de webjunkie semble meilleure. J'apprends juste Django moi-même. –

+0

En général, il n'y a aucune raison de mentionner explicitement le champ id dans l'ORM. En supposant que vous avez une instance Auteur, vous voudriez Book.objects.filter (authorbook__author = author). Mais un ManyToManyField est la voie à suivre, bien sûr. –

14

"AuthorBook" ne semble pas correctement modélisé.

Vous devez utiliser un ManyToManyField:

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

Ensuite, vous pouvez faire:

books = Book.objects.filter(authors__id=1) 
+1

+ 1 pour suggérer ManyToManyField (c'est la façon Django), -1 pour ne pas savoir que c'est comme ça que ça se passe "sous le capot". – Javier

+5

Bien sûr, les relations m2m utilisent des tables intermédiaires. Cependant, il n'est pas correctement modélisé avec Django dans ce cas. Ça ne sert à rien de me faire comprendre que je sais comment ça marche sous le capot. – webjunkie

Questions connexes