web-dev-qa-db-ja.com

Djangoを含む多対多のフィルター

私は、多対多の関係を通してオブジェクトの束をフィルター処理しようとしています。 trigger_rolesフィールドには複数のエントリが含まれる可能性があるため、私は含むフィルタを試しました。しかし、それは文字列で使用するように設計されているため、この関係をフィルタリングする方法はほとんど無力です(values_list()atmを無視できます)。

この関数はユーザープロファイルに添付されます。

def getVisiblePackages(self):
    visiblePackages = {}   
    for product in self.products.all():
        moduleDict = {}
        for module in product.module_set.all():
            pkgList = []
            involvedStatus = module.workflow_set.filter(trigger_roles__contains=self.role.id,allowed=True).values_list('current_state', flat=True)

私のワークフローモデルは次のようになります(簡略化)。

class Workflow(models.Model):
    module = models.ForeignKey(Module)
    current_state = models.ForeignKey(Status)
    next_state = models.ForeignKey(Status)
    allowed = models.BooleanField(default=False)
    involved_roles = models.ManyToManyField(Role, blank=True, null=True)
    trigger_roles = models.ManyToManyField(Role, blank=True, null=True)

解決策は静かでシンプルかもしれませんが、私の脳は教えてくれません。

ご協力いただきありがとうございます。

66
Grave_Jumper

このようなことを試しましたか:

module.workflow_set.filter(trigger_roles__in=[self.role], allowed=True)

または単にself.role.idは、pksのリストではありません。

module.workflow_set.filter(trigger_roles__id__exact=self.role.id, allowed=True)
88
mouad

これを達成するための最も簡単なアプローチは、ManyToManyFieldの(idではなく)インスタンス全体の同等性をチェックすることです。インスタンスが多対多の関係内にあるかどうかを確認します。例:

module.workflow_set.filter(trigger_roles=self.role, allowed=True)
15
Caumons

最初の例では、特異点はほぼ正しいです。それがリストであることを確認する必要があります。ただし、trigger_roles__id__exactを確認する2番目の例は、より良い解決策です。

module.workflow_set.filter(trigger_roles__in=[self.role.id],allowed=True)
4
Josh Smeaton

これは古い質問ですが、OPは彼が探していた答えをまったく得ていないようです。比較するManyToManyFieldsのセットが2つある場合、トリックはcontainsではなく___in_演算子を使用することです。たとえば、フィールドeventgroupsに "グループ"にManyToManyを持つ "イベント"モデルがあり、ユーザーモデルが(明らかに)グループにアタッチしている場合、次のようにクエリできます。

Event.objects.filter(eventgroups__in=u.groups.all())

3
shacker