2016-09-15 21 views
0

私は以下の2つのDjangoクラスMyClassAMyClassBを持っています。Django ManyToManyFieldで重複を取らずにORを実行するにはどうすればいいですか?

>>> a = MyClassA.objects.create(name="A") 
>>> b = MyClassA.objects.create(name="B") 
>>> c = MyClassA.objects.create(name="C") 
>>> d = MyClassA.objects.create(name="D") 
>>> e = MyClassA.objects.create(name="E") 
>>> u = MyClassB.objects.create(name="U") 
>>> u.my_class_as.add(c) 
>>> u.my_class_as.add(d) 
>>> u.save() 

私はの(ユニーク)のリストを見つけたい:

MyClassBは、その後、私は次のようなデータでデータベースをシードMyClassA

from django.db import models 

class MyClassA(models.Model): 
    name = models.CharField(max_length=50, null=False) 

    def __str__(self): 
     return "<%s %s>" % (
     self.__class__.__name__, "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ])) 

class MyClassB(models.Model): 
    name = models.CharField(max_length=50, null=False) 
    my_class_as = models.ManyToManyField(MyClassA, related_name="MyClassB_my_class_as") 

    def __str__(self): 
     return "<%s %s>" % (
     self.__class__.__name__, "; ".join(["ID: %s" % self.pk, "name: %s" % self.name, ])) 

の多対多のフィールドを持っていますMyClassAのインスタンスcまたはdとの関係を持つMyClassB。私はどうすればいいのですか?

@staticmethod 
def is_m2m_related_queryset(my_class_a_list): 
    q = Q() 
    for curr_a in my_class_a_list: 
     q |= Q(my_class_as=curr_a) 
    return q 

...そして次のクエリを実行します:

>>> MyClassB.objects.filter(MyClassB.is_m2m_related_queryset([c, d])) 
[<MyClassB: <MyClassB ID: 11; name: U>>, <MyClassB: <MyClassB ID: 11; name: U>>] 

をしかし、待って

私のソリューションは、MyClassB上の次の静的メソッドを作成することでした! 期待通りにuオブジェクトを含むシングルトンリストを私に返す代わりに、このクエリーセットは[u, u]を返します。それは私が望むものではありません。 この返信しないでください[u] ?? なぜそれが何を返したのですか?

私は欲しいものをどのように取得する必要がありますか?クエーセットに.distinct()を追加するだけでいいですか?または私のquerysetを構築するためのより良い/より効率的ですか?

EDIT:

私はアンドレイのソリューションは、以下の提案(およびその変異体)を試みたが、それはどちらか動作しませんでした:

>>> MyClassB.objects.filter(my_class_as__pk__in=[c.pk, d.pk]) 
[<MyClassB: <MyClassB ID: 1; name: U>>, <MyClassB: <MyClassB ID: 1; name: U>>] 

>>> MyClassB.objects.filter(my_class_as__in=[c, d]) 
[<MyClassB: <MyClassB ID: 1; name: U>>, <MyClassB: <MyClassB ID: 1; name: U>>] 

答えて

1

あなたが試してみました:

MyClassB.objects.filter(my_class_as__pk__in=[c.pk, d.pk])? 
+0

をはい、オリジナルの質問の編集をご覧ください。それは異なる結果をもたらさなかった。 –

+1

ああ、最後に 'distinct()'を追加するだけです。それはあなたに一意のオブジェクトを与えます。 –

関連する問題