Django-filter '__in' lookup

2020-03-15 02:24发布

I am using django-rest-framework with https://github.com/alex/django-filter/, but question is mostly about django-filter. I can't understand how to use filters with "__in" lookup.

For example i have model:

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

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

And i can't use url like this

/v1/books/?id__in=1,2,3

to find books with id 1, 2 or 3

标签: python django
9条回答
Deceive 欺骗
2楼-- · 2020-03-15 02:58

There's a simple solution with django_filter now:

class BookView(viewsets.ReadOnlyModelViewSet):
   serializer_class = BookSerializer()
   model = Book
   filter_fields = {
      'id': ['exact', 'in'],
      'name': ['exact']
   }

And then you can use it in your query string exactly as you wanted: ?id__in=1,2,3.

查看更多
Explosion°爆炸
3楼-- · 2020-03-15 03:04

Customize PKsField and PKsFilter for your id field(AutoField), and then the query params will work: '/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

Hope that can help. Thx.

查看更多
老娘就宠你
4楼-- · 2020-03-15 03:04

Not sure if this was ever answered: try: id=[1, 2, 3] for numbers name=["name1", "name2"] for strings

查看更多
登录 后发表回答