web-dev-qa-db-fra.com

Django ManyToMany filter ()

J'ai un modèle:

class Zone(models.Model):
    name = models.CharField(max_length=128)
    users = models.ManyToManyField(User, related_name='zones', null=True, blank=True)

Et je dois construire un filtre dans le sens de:

u = User.objects.filter(...zones contains a particular zone...)

Il doit s'agir d'un filtre sur l'utilisateur et d'un paramètre de filtre unique. La raison en est que je construis une chaîne de requête d'URL pour filtrer la liste de modifications de l'utilisateur administrateur: http://myserver/admin/auth/user/?zones=3

Il semble que cela devrait être simple mais mon cerveau ne coopère pas!

103
Andy Baker

Je répète juste ce que Tomasz a dit.

Il existe de nombreux exemples de FOO__in=... filtres de style dans les tests plusieurs-à-plusieurs et plusieurs-à-un . Voici la syntaxe pour votre problème spécifique:

users_in_1zone = User.objects.filter(zones__id=<id1>)
# same thing but using in
users_in_1zone = User.objects.filter(zones__in=[<id1>])

# filtering on a few zones, by id
users_in_zones = User.objects.filter(zones__in=[<id1>, <id2>, <id3>])
# and by zone object (object gets converted to pk under the covers)
users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3])

La syntaxe double underscore (__) est utilisée partout lorsque vous utilisez querysets .

124
istruble

Notez que si l'utilisateur peut se trouver dans plusieurs zones utilisées dans la requête, vous souhaiterez probablement ajouter .distinct (). Sinon, vous obtenez un utilisateur plusieurs fois:

users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3]).distinct()
24
QB.