Django-filter'__in'查找

use*_*813 8 python django

我使用的是django-rest-framework和https://github.com/alex/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')
Run Code Online (Sandbox Code Playgroud)

我不能像这样使用网址

/ V1 /书籍/?id__in = 1,2,3

找到id为1,2或3的书籍

ude*_*tha 10

django-filter 可以BaseInFilter与其他过滤器类结合使用,例如NumberFilter, CharFilter。此类仅验证传入请求是否为comma-separated。因此,如果您使用 Web Browsable API,则可以将请求发送为 /book/?id__in=1 %2C3 (其中%2C是逗号)。

过滤器.py

import django_filters


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


class BookFilter(django_filters.FilterSet):
    id__in = NumberInFilter(field_name="id", lookup_expr="in")
Run Code Online (Sandbox Code Playgroud)

视图.py

from rest_framework import viewsets
from django_filters import rest_framework as filters

from book.filters import BookFilter
from book.models import Book
from book.serializers import BookSerializer


class BookViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    filter_backends = (filters.DjangoFilterBackend, )
    filterset_class = BookFilter
    serializer_class = BookSerializer
Run Code Online (Sandbox Code Playgroud)


Omr*_*tix 7

这个问题在本期中讨论:https://github.com/alex/django-filter/issues/137#issuecomment-77697870

建议的解决方案是创建自定义过滤器,如下所示:

from django_filters import Filter
from django_filters.fields import Lookup

from .models import Product

class ListFilter(Filter):
    def filter(self, qs, value):
        value_list = value.split(u',')
        return super(ListFilter, self).filter(qs, Lookup(value_list, 'in'))

class ProductFilterSet(django_filters.FilterSet):
    id = ListFilter(name='id')

    class Meta:
        model = Product
        fields = ['id']
Run Code Online (Sandbox Code Playgroud)

你可以写下面的内容:

产品/?ID = 7,8,9


sga*_*ble 7

django_filter现在有一个简单的解决方案:

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

然后您可以完全按照您的需要在查询字符串中使用它:?id__in=1,2,3


小智 -2

django 管理站点仅在模板 app_name/model_name/primary_key 下创建 url 来编辑模型的实例。它不提供__in通过 URLS 的过滤。

您必须创建一个自定义视图:

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) )
Run Code Online (Sandbox Code Playgroud)

在 mytemplate.html 中:

{% for entry in selected_books %}
  ... {{ entry }} ...
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

在 urls.py 中向该视图添加一个条目。

然后尝试使用参数向您的 URL 发出 GET 请求?ids=1_2_3