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 j'ai besoin de construire un filtre sur le modèle de:
u = User.objects.filter(...zones contains a particular zone...)
Il doit s'agir d'un filtre sur l'utilisateur et d'un seul paramètre de filtre. La raison en est que je construis une chaîne de requête URL pour filtrer la liste des 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!
django
django-models
Andy Baker
la source
la source
User.objects.filter(zones__id=<id>)
ouUser.objects.filter(zones__in=<id(s)>)
bon pour cela?User.objects.filter(zones__in=<id(s)>)
devrait probablement êtreUser.objects.filter(zones__id__in=<id(s)>)
Réponses:
Je répète simplement 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 de votre problème spécifique:La syntaxe du double trait de soulignement (__) est utilisée partout lorsque vous travaillez avec des ensembles de requêtes .
la source
...__in
exemples après# filtering on a few zones, by id
. Ceux-ci affichent le filtrage pour plusieurs identifiants / objets (dans ce cas). Passez simplement les identifiants / objets zone1, zone3 et zone10 qui vous intéressent. Ou ajoutez un 4e si nécessaire.Notez que si l'utilisateur se trouve dans plusieurs zones utilisées dans la requête, vous souhaiterez probablement ajouter .distinct (). Sinon, vous obtenez un utilisateur plusieurs fois:
la source
une autre façon de faire est de passer par le tableau intermédiaire. J'exprimerais ceci dans l'ORM Django comme ceci:
ce serait bien s'il n'avait pas besoin du
.values('user')
spécifié, mais Django (version 3.0.7) semble en avoir besoin.le code ci-dessus finira par générer du SQL qui ressemble à quelque chose comme:
ce qui est bien car il n'a pas de jointures intermédiaires qui pourraient entraîner le retour d'utilisateurs en double
la source