2017-10-13 6 views
0

Les utilisateurs de mon application peuvent bloquer d'autres utilisateurs afin que les utilisateurs bloqués ne verront pas leurs bloqueurs n'importe où dans l'application. Je les modèles suivantsDjango ORM Multicolumn rejoindre

class User(models.Model): 
    blocked_users = models.ManyToManyField(
     'self', symmetrical=False, through='Block') 


class Block(models.Model): 
    class Meta: 
     unique_together = ('from_user', 'to_user') 

    from_user = models.ForeignKey('User', related_name='blocked') 
    to_user = models.ForeignKey('User', related_name='blocked_by') 

Alors maintenant, je suis en train de faire Django faire la requête suivante qui renverra les utilisateurs qui ne bloque pas utilisateur actuellement connecté.

SELECT * 
FROM user 
LEFT OUTER JOIN block ON (block.from_user_id = user.id AND block.to_user_id = 1) 
WHERE block.id is null 

1 est l'ID de l'utilisateur actuellement connecté.

Répondre

0

qu'en est-il de .exclude()?

User.objects.exclude(blocked_by__to_user__id=request.user.id) 

peut-être plus efficace quelque chose comme:

User.objects.filter(user__blocked_by__to_user=request.user.id, blocked_by__is_null=True) 
+0

Cette queryset génère requête qui utilise pour exclure sous-requête. C'est beaucoup moins efficace que de se joindre –

+0

Je ne peux pas reproduire votre configuration maintenant, mais juste mis à jour la réponse avec un indice. Comme votre M2M fait référence à vous-même, vous devriez disposer de la relation auto pour filtrer. – efkin