2010-02-07 15 views
69

Mam model:filtr Django ManyToMany()

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

I muszę contruct filtr wzdłuż linii:

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

To musi być filtr na użytkownika i ma być pojedynczym parametrem filtru. Powodem tego jest to, że buduję URL, aby filtrować listę zmian admin: http://myserver/admin/auth/user/?zones=3

Wygląda na to, że powinno być proste, ale mój mózg nie współpracuje!

+7

Nie jestem pewien, czy mogę Ci rację - nie jest 'User.objects.filter (zones__id = )' lub 'User.objects.filter (zones__in = ) "dobre dla tego? –

+0

To dobrze :) BTW 'User.objects.filter (zones__in = )' prawdopodobnie powinien być 'User.objects.filter (zones__id__in =)' –

+10

Po prostu chciałbym wskazać każdemu, kto to zrobi, że działa tylko wtedy, gdy related_name jest ustawiony. zone_set nie zadziała, na przykład. Zmarnował dobre pół godziny :-) –

Odpowiedz

77

Po prostu to, co powiedział Tomasz.

Istnieje wiele przykładów filtrów w stylu FOO__in=... w testach i many-to-one. Oto składnia dla konkretnego problemu:

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

Składnia podwójne podkreślenia (__) jest używany w każdym miejscu podczas pracy z querysets.

+0

link do dokumentu jest teraz zepsuty, ale dziękuję istruble! – maxm

+0

Dzięki @maxm. Zaktualizowano bieżący link do niektórych przykładów. – istruble

+0

link jest zerwany – maazza

10

Należy pamiętać, że jeśli użytkownik może znajdować się w wielu strefach używanych w zapytaniu, prawdopodobnie warto dodać .distinct(). W przeciwnym razie można dostać jeden użytkownik wielokrotnie:

users_in_zones = User.objects.filter(zones__in=[zone1, zone2, zone3]).distinct() 
Powiązane problemy