2

これはdjango-filterアプリ固有のゲストです。

条件に従ってクエリするフィルターの条件を導入しようとした人はいますか?

例を挙げましょう:

Productモデルがあるとします。nameおよびに従ってフィルタリングできますprice

デフォルトのdjango-filter動作では、より多くのフィルターを使用してそれらを連鎖させると、ANDステートメントを使用してデータをフィルター処理します (検索を絞り込みます)。

この動作を変更して ChoiceFilter を追加したいと思いANDますOR。この時点から、フィルターはユーザーが選択したものに従って機能するはずです。

例えば。ユーザーが の製品をクエリした場合、name__startswith="Juice" OR price__lte=10.00名前が で始まるすべての製品とJuice、価格が より下の製品が一覧表示されます10.00

Django-filterdocs は、フィルターが引数を取ることができると言います:

action

An optional callable that tells the filter how to handle the queryset. It recieves a 
QuerySet and the value to filter on and should return a Queryset that is filtered 
appropriately.

これは私が探しているもののようですが、ドキュメントにはそれ以上の説明がありません。提案してください?

@編集:

これはviews.py次のとおりです。

def product_list(request):
    f = ProductFilter(request.GET, queryset=Product.objects.all())
    return render_to_response('my_app/template.html', {'filter': f})
4

4 に答える 4

4

最終的なクエリセットが構築される方法が原因で、各フィルターを一緒に ORed にすることは困難です。基本的に、コードは次のように機能します。

FilterSet、filterset.py 行 253 :

@財産
デフォルトqs(自己):
    qs = self.queryset.all()
    self.filters() の filter_ の場合:
        qs = filter_.filter(qs)

フィルター、filters.py 行 253 :

デフォルトフィルター (自己、qs):
    return qs.filter(name=self.value)

各フィルターは、受信クエリセットにそれ自体を適用する方法を決定できます。現在実装されているすべてのフィルターは、AND を使用して受信クエリセットをフィルター処理します。入力クエリセットに対して OR を使用する新しいフィルター セットを作成することはできますが、FilterSet 側から動作をオーバーライドする方法はありません。

于 2013-09-23T00:30:33.647 に答える
2

フィルターを OR で機能させるには、FilterSet のサブクラスを作成し、次のように Tim の回答から qs をオーバーライドする必要があります。

@property
def qs(self):
    qs = self.queryset.none()
    for filter_ in self.filters():
        qs |= filter_.filter(self.queryset.all())

私はこれをテストしていませんが、あなたはアイデアを得たと思います。QuerySet はビット演算をサポートしているため、2 つのフィルターの結果を OR で簡単に組み合わせることができます。

于 2013-09-23T06:42:27.787 に答える
1



class FileFilterSet(django_filters.FilterSet):
    class Meta:
        model = File
        fields = ['project']

    def __init__(self, *args, **kwargs):
        super(FileFilterSet, self).__init__(*args, **kwargs)

        for name, field in self.filters.items():
            if isinstance(field, ModelChoiceFilter):
                field.extra['empty_label'] = None
                field.extra['initial'] = Project.objects.get(pk=2)
                # field.extra['queryset'] = Project.objects.filter(pk=2)


class FileFilter(FilterView):
    model = File
    template_name = 'files_list.html'
    filterset_class = FileFilterSet

于 2015-12-13T08:27:11.770 に答える