Каков наилучший способ django выполнить запрос, который охватывает несколько таблиц?

У меня есть обзоры / рейтинги веб-приложения, a la Digg. В моем приложении для приложения django есть следующая модель:

 class Content(models.Model): title = models.CharField(max_length=128) url = models.URLField(max_length=2048) description = models.TextField(blank=True) class Recommendation(models.Model): user = models.ForeignKey(User) content = models.ForeignKey(Content) review = models.TextField() rating = models.PositiveSmallIntegerField() class Meta: unique_together = ('user', 'content') class Subscription(models.Model): subscriber = models.ForeignKey(User, related_name='subscription_set') publisher = models.ForeignKey(User, related_name='publication_set') class Meta: unique_together = ('subscriber', 'publisher') 

Я хочу создать страницу со всеми рекомендациями всех пользователей, которым подписывается текущий пользователь ( request.user ).

Если я напишу это в SQL, я верю, что у меня будет запрос, похожий на следующий:

 select content_content.*, content_recommendation.*, auth_user.* from content_content, content_recommendation, content_subscription, auth_user where content_content.id = content_recommendation.content_id and content_recommendation.user_id = content_subscription.publisher_id and content_subscription.subscriber_id = ? and auth_user.id = content_subscription.publisher_id; 

Как я могу выразить это с помощью API запросов Django? Я читал документы, но просто не могу обойти его.

Я хотел бы использовать:

 Recommendation.objects.filter(user__publication_set__subscriber=request.user).select_related() 

По мере того, как вы просили, вы получите все объекты Рекомендации, а select_related будет загружать все связанные объекты пользователя и содержимого в память, чтобы последующий доступ к ним снова не ударил по БД.

То, как вы могли бы конкретизировать этот запрос, действительно имеет много общего с обработкой возвращаемых данных впоследствии. Возможно, более или менее эффективно идти в одну сторону против другой, основываясь на том, что вы с ней делаете. alt text http://sonicloft.net/im/52

Я думаю, что это:

  Content.objects.filter(recommendation_set__user__publication_set__subscriber__pk=request.user.pk)/.distinct()/ 

или

  Recommendation.objects.filter(user__publication_set__subscriber__pk=request.user.pk)/.distinct()/ 

– в зависимости от того, какую модель вы хотите получить. Для избежания дубликатов может потребоваться различать ().