17

パッケージでDjango RESTフレームワークを使用していdjango-filterますが、私の質問は主にdjango-filter. 「__in」ルックアップでフィルターを使用する方法がわかりません。

たとえば、次のモデルがあります。

class Book(models.Model):
   name = models.CharField(max_length=100)

class BookView(viewsets.ReadOnlyModelViewSet):
   serializer_class = BookSerializer()
   model = Book
   filter_fields = ('id', 'name')

/v1/books/?id__in=1,2,3また、ID 1、2、または 3 の書籍を検索するような URL を使用することはできません。

Django-filter の '__in' ルックアップをどのように使用しますか?

4

9 に答える 9

3

django-filter のドキュメントはまばらです。カスタム フィルターを作成し、ルックアップ タイプを指定してみてください。それはかなり複雑です:

class BookFilter(django_filters.FilterSet):
    id = django_filters.NumberFilter(name="id", lookup_type="in")

    class Meta:
        model = Book
        fields = ['id']

次に、フィルター クラスを使用するようにビューを変更します。

class BookView(viewsets.ReadOnlyModelViewSet):
    serializer_class = BookSerializer()
    model = Book
    filter_fields = ('id', 'name')
    filter_class = BookFilter

その後、ID を介して書籍を検索できるようになります (「__in」は使用されないことに注意してください)。

/v1/books/?id=1,2,3
/v1/books/?id=1
于 2014-04-08T06:06:16.020 に答える
2

id フィールド (AutoField) の PKsField と PKsFilter をカスタマイズすると、クエリ パラメータが機能します: '/v1/books/?id__in=1,2,3'

from django.forms import Field
from django_filters.filters import Filter
from django.db.models import AutoField


class PKsField(Field):

    def clean(self, value): # convert '1,2,3' to {1, 2, 3}
        return set(int(v) for v in value.split(',') if v.isnumeric()) if value else ()


class PKsFilter(Filter):
    field_class = PKsField


class BookFilter(FilterSet):
    # ids = PKsFilter(name='id', lookup_type="in") # another way, query string: ?ids=1,2,3

    filter_overrides = {
        AutoField: {
            'filter_class': PKsFilter, # override default NumberFilter by the PKsFilter
            'extra': lambda f: {
                'lookup_type': 'in',
            }
        }
    }

    class Meta:
        model = Book
        fields = {
            'id': ('in',),
        }


from rest_framework import viewsets


class BookView(viewsets.ModelViewSet):
    queryset = ...
    serializer_class = ...
    filter_class = BookFilter

それが役立つことを願っています。どうも。

于 2015-01-28T03:45:37.780 に答える
0

複数のIDを持つDjangoFilterBackendで同じ質問に答えました

あなたの場合、これはロジックを書かなくてもうまくいくはずです。

from django_filters import rest_framework as filters

class NumberInFilter(filters.BaseInFilter, filters.NumberFilter):
    pass


class BookFilter(filters.FilterSet):
    id_in = NumberInFilter(field_name='id', lookup_expr='in')

    class Meta:
        model = Book
        fields = ['id_in', 'name']

class BookView(viewsets.ReadOnlyModelViewSet):
   serializer_class = BookSerializer()
   model = Book
   filter_class = BookFilter

これで、次のような get パラメータの ID のリストでフィルタリングできるはずです。/v1/books/?id__in=1,2,3

于 2019-05-07T15:17:56.180 に答える
-1

django 管理サイトは、モデルのインスタンスを編集するためのテンプレート app_name/model_name/primary_key の下にのみ URL を作成します。__inURL によるフィルタリングは提供しません。

カスタム ビューを作成する必要があります。

def myview(request):
    # you can get parameters from request.GET or request.POST
    selected_books = None
    if request.method = "POST":
        ids = request.POST["ids"].split("_")
        selected_books = Book.objects.filter(id__in=ids)

    return render_to_response('mytemplate.html', { 'selected_books': selected_books }, context_instance = RequestContext(request) )

そして mytemplate.html で:

{% for entry in selected_books %}
  ... {{ entry }} ...
{% endfor %}

urls.py で、このビューにエントリを追加します。

次に、パラメーターを使用して URL への GET 要求を試みます?ids=1_2_3

于 2013-08-02T12:40:50.963 に答える