Supposons que je ce modèle:Django LEFT JOIN, efficacement?
class PhotoAlbum(models.Model):
title = models.CharField(max_length=128)
author = models.CharField(max_length=128)
class Photo(models.Model):
album = models.ForeignKey('PhotoAlbum')
Et je veux faire cette requête: « Trouver 10 albums dont le nom commence par « Le », puis me donner toutes les photos de ces albums. »
Dans SQL je pouvais faire quelque chose comme ceci:
SELECT * FROM
(SELECT * FROM photoalbum WHERE title LIKE 'The%' LIMIT 10) AS selected_albums
LEFT JOIN photo ON photo.album_id = selected_albums.id
Ma question est, comment puis-je faire cela dans Django? (SANS DÉCLENCHER UNE QUESTION POUR CHAQUE ALBUM!) Je suppose que c'est une exigence assez commune, et je ne peux pas croire qu'il n'y a pas moyen de le faire.
S'il n'y a pas de manière Django-ey, je me contenterai de "comment puis-je l'implémenter dans Django en utilisant du SQL brut?".
Voici quelques choses qui ne fonctionnent pas:
select_related()
; C'est pour avantForeignKey
relations, c'est en arrière.Edit: En fait, ce fonctionne! Au moins pour un niveau deprefetch_related()
; également pour les relations à terme.ForeignKey
s.PhotoAlbum.photo_set
; qui déclenche une requête pour chaque album.Le plus proche que j'ai est:
albums = PhotoAlbum.objects.all() [: 10] Photos = Photo.objects.filter (album__in = albums)
Mais il ne fonctionne malheureusement pas sur MySQL, et on m'a dit qu'il vaut mieux utiliser LEFT JOIN
que la requête de type WHERE ... IN (SELECT ...)
que cela crée.
Modifier
J'ai trouvé un 3 year old mailing list post about the problem. Aucune solution à l'intérieur.
A 6 year old bug report saying they won't fix it. Aucune raison donnée autre que "ce n'est pas comme ça que ça fonctionne". Apparemment, il est possible dans RoR si.
Cela fonctionne! Il utilise 'WHERE id IN (1, 2, 3, 4, 5, 6)' au lieu de 'LEFT JOIN' mais assez juste. Maintenant, je veux chaîner 'prefetch_related()' à deux niveaux de reverseKey 'ForeignKey's, mais je vais laisser cela pour une autre fois. À votre santé. – Timmmm