Queryset of Project.objects.all()を使用し、ユーザが選択した属性のリストを含むすべてのプロジェクトをフィルタリングしたいと考えています。Django QuerysetフィルタリングでManytomanyをフィルタリングする
class Attribute(models.Model):
title = models.CharField(max_length=20)
class Project(models.Model):
title = models.CharField(max_length=30)
attributes = models.ManyToManyField(Attribute)
## For the sake of this example, there are two Projects and two Attributes
## Project1 is associated to attr1 and attr2
## Project2 is associated to attr1
models.py私は、この発見:Django Docs Complex Lookups with Q objectsをし、他のstackoverflowの答えによって、ここに着い:(self.multiselectは、PKSのリストである)
非稼働コード
query = reduce(operator.and_, (Q(attributes__pk=selection) for selection in self.multiselect))
return queryset.filter(query)
ただし、このコードは空のクエリセットを提供します。インタラクティブシェルでいくつかのテストを行い、何がうまくいかないかを調べ始めました。 &プロジェクトと属性間の多対多の関係で動作していないように思え
テスト
queryset = Project.objects.all()
########## & is not working
queryset.filter(Q(attributes__pk=1) & Q(attributes__pk=2))
# []
########## | has no issues
queryset.filter(Q(attributes__pk=1) | Q(attributes__pk=2))
# [<Project: Project1>, <Project: Project2>, <Project: Project1>]
########## & works on Project but not on Attribute
queryset.filter(Q(title__contains="Project") & Q(title__contains="1"))
# [<Project: Project1>]
。これには理由がありますか、それが正しく動作するようにするコードには簡単な修正がありますか?どんな助けもありがとう。サイドノートとして
、reduce関数は、私がなぜfilter
、Q
と&
作品を理解していない、まさにそれが必要
########## Reduce does not create an issue
Q(attributes__pk=1) & Q(attributes__pk=2)
# <Q: (AND: ('attributes__pk', 1), ('attributes__pk', 2))>
reduce(operator.and_, [Q(attributes__pk=selection) for selection in [1,2]])
# <Q: (AND: ('attributes__pk', 1), ('attributes__pk', 2))>
いや:
はこれを参照してください。私はこれの背後にある数学を理解しようとしていますが、望ましい出力が得られるようです。ありがとうございます<3編集:否定によって私の望む出力以外のすべてが得られるので、 'filter'、 'Q'、 '&'のバグがなければならないと思います。望ましい結果。ニースキャッチ^^ – pieisawesome102
あなたを助けてうれしいです。 –