2017-08-14 18 views
0

filter多対多の中間関係を介して2番目のモデルに接続されているDjangoモデルです。djangoフィルタ多対多リスト

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
     return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

design and expected result

彼はエントリー1と会員による2にグループに接続されているため、結果は唯一の人物Aを選択するようにする必要があります。この種の作業にはQオブジェクトを使用したいと思います。

誰でも私にヒントを教えてもらえますか?

答えて

1

私はあなたがIdsはあなたにそれを提供するすべてのグループにあるすべてのオブジェクトPersonをしたいと思います。

ソリューション:ここ

from django.db.models import Q 

person_qs = Person.objects.exclude(~(Q(group__id=1) & Q(group__id=2))) 

、私は1ではありませんすべてのグループIDを除外するためにexcludeを使用し、2

あなたがグループIDをたくさん持っている場合、あなたはreduceを使用することができますし、 operatorを使用して、単一のforループでクエリを構築します。

from functools import reduce 
import operator 

query = reduce(operator.and_, (Q(group__id=group_id) for group_id in group_ids)) 

persons_qs = Person.objects.exclude(~query) 

これ、

+0

これはまさに私が探していたものです!どうもありがとう! – essin

2

ここでQを使う必要はありません。単純なクエリです。

Person.objects.filter(group__id__in=[1, 2]) 
+0

(...など)Q(group__id=1) & Q(group_id=2) &のようなクエリを形成することになる。しかし、これはINはORのような役割を果たしてBが正しいaswell返すでしょうか? – essin