2010-03-24 4 views
2

J'ai une application web de critiques/évaluations, à la Digg. Mon django application content a le modèle suivant:Quelle est la meilleure façon de django de faire une requête qui s'étend sur plusieurs tables?

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') 

Je veux construire une page avec toutes les recommandations de tous les utilisateurs auxquels un utilisateur actuel (request.user) est abonnée.

Si j'écris ceci dans SQL, je crois que je vais finir avec une requête similaire à ce qui suit:

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; 

Comment pourrais-je exprimer cela en utilisant les API de requête de Django? J'ai lu les documents, mais je n'arrive pas à comprendre.

Répondre

10

J'utiliser:

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

que vous obtiendrez tous les objets Recommandation que vous avez demandé, et le select_related chargera tous les utilisateurs associés et les objets contenus dans la mémoire afin que l'accès ultérieur d'entre eux ne frapper à nouveau la DB. Cependant, la manière dont vous construisez cette requête a beaucoup à voir avec votre gestion des données renvoyées par la suite. Il peut être plus ou moins efficace d'aller d'une façon ou d'une autre en fonction de ce que vous en faites. alt text http://sonicloft.net/im/52

1

Je pense qu'il est:

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

ou

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

- selon le cas du modèle que vous voulez obtenir. Distinct() peut être nécessaire pour éviter les doublons.

Questions connexes