3

django.db.models.Q操作対象のニュートラル要素とは|?関数を使用してフィルターを生成したい:

MyModel.objects.filter(myfunc(args)) where myfunc should give something like: "Q(foo) | Q(bar) | ... | False"

Falseしかし、私はQオブジェクトが何であるかわかりません。同様に、&操作にはニュートラル要素が必要です ( True)...

このような関数の例を次に示します。

# Models
class MyModel(models.Model):
    myfield1 = models.CharField(max_length=30)
    myfield2 = models.CharField(max_length=30)


# Views
class MyView(views.View):
    model = MyModel

    def get_queryset(self):
        def myfunc(query_object_list, param):
            myfuncr = lambda l: ((myfuncr(l[1:]) | Q(**{ param: l[0] })) if l else Q(False)) # "Q(False)" would be the neutral element of operation "|" for Q objects
            return myfuncr(query_object_list)

        myq = Q(True) # "Q(True)" would be the neutral element of operation "&" for Q objects
        for param in self.request.GET:
            myq &= myfunc(self.request.GET.getlist(param, None), param)

        return MyModel.objects.filter(myq)


# Template
<a href='{% url myview %}?myfield1__iexact={{ myvar1 }}&myfield2__iexact={{ myvar2 }}'>foobar</a>
4

3 に答える 3

7

私はついに解決策を見つけました。それは実際には非常に単純でした...Qオブジェクトの「中立要素」。これは操作「|」でも同じです。「&」は「Q()」です

テンプレートに必要なものすべてに一致する動的フィルターができました...

# Models
class MyModel(models.Model):
    myfield1 = models.CharField(max_length=30)
    myfield2 = models.CharField(max_length=30)
    myinteger3 = models.IntegerField(blank=True, null=True)



# Views
class MyView(views.View):
    model = MyModel

    def get_queryset(self):
        def myfunc(query_object_list, param):
            myfuncr = lambda l: ((myfuncr(l[1:]) | Q(**{ param: l[0] })) if l else Q()) # Q() is the neutral element of operation "|" for Q objects
            return myfuncr(query_object_list)

        myq = Q() # Q() is the neutral element of operation "&" for Q objects
        for param in self.request.GET:
            myq &= myfunc(self.request.GET.getlist(param, None), param)

        return MyModel.objects.filter(myq)


# Template
<a href='{% url myview %}?myfield1__iexact={{ myvar1 }}&myfield2__iexact={{ myvar2 }}&myinteger3__gte={{ myvar3 }}'>foobar</a>

<a href='{% url myview %}?myinteger3__gte={{ myvar4 }}'>{{ myvar4 }}</a>
于 2012-12-13T18:07:22.823 に答える
2

誰も気にしない。

myq = reduce(operator.and_, (myfunc(self.request.GET.getlist(param, None), param) for param in self.request.GET))
于 2012-12-13T16:36:25.283 に答える
0

あなたが何をしようとしているのかよくわかりませんが、この文脈では質問が実際には意味をなさないと思います. &andは実際にはオブジェクトの|ブール演算子ではありません:コードはandメソッドをオーバーライドして、引数をツリーに結合します。これは、Django が SQL に変換する前にクエリを内部的に表現する方法です。Q__and____or__

于 2012-12-13T11:32:19.313 に答える