django - 创建自定义过滤器

标签 django django-rest-framework django-filter

目前我的看法如下:

from rest_framework.permissions import AllowAny
from dynamic_rest.viewsets import DynamicModelViewSet
from django_filters.rest_framework import DjangoFilterBackend

from .models import Purchase
from .serializers import PurchaseSerializer


class PurchasesViewSet(DynamicModelViewSet):
    queryset = Purchase.objects.all()
    serializer_class = PurchaseSerializer
    permission_classes = (AllowAny,)
    filter_backends = (DjangoFilterBackend,)
    filter_fields = ('name', 'color')

这允许我按精确的名称颜色进行过滤。

我的数据有一个日期字段(DateField类型)。我想按“季度”创建一个自定义过滤器,以便这种请求:

/purchases/?quarter=2018Q1

提供指定季度内带有日期字段的对象列表。请注意,quarter 不是模型字段。

创建这样一个自定义过滤器的方法是什么?

最佳答案

首先,您必须创建自定义过滤器以及过滤器类

import django_filters
from rest_framework.exceptions import ValidationError


class QuarterFilter(django_filters.Filter): # Custom Filter
    def get_quarter_range(self, quarter):
        if quarter == 1:
            return [1, 3]
        elif quarter == 2:
            return [4, 6]
        elif quarter == 3:
            return [7, 9]
        elif quarter == 4:
            return [10, 12]
        else:
            raise ValidationError("quarter value must be range from 1-4")

    <b>def filter(self, qs, value):
        """
        create your custom filtering logi here
        """
        # here the "value" will be the value parsed from URL params, ie "2018Q1"
        try:
            year, quarter = value.split("Q") # spliting the input to get year and quarter value
            qs = qs.filter(date__year=year)

            qs = qs.filter(date__month__range=self.get_quarter_range(quarter))
            return qs
        except:
            return qs</b>


class PurchaseFilter(django_filters.FilterSet): # Custom Filter Class
    <b>quarter = QuarterFilter()</b>

    class Meta:
        model = Purchase
        fields = ['name', 'color', <b>'quarter'</b>]



然后,在您的 View 类中使用 filterset_class 提及它属性。那么你的观点是这样的,

class PurchasesViewSet(DynamicModelViewSet):
    queryset = Purchase.objects.all()
    serializer_class = PurchaseSerializer
    permission_classes = (AllowAny,)
    filter_backends = (DjangoFilterBackend,)
    <b># filter_fields = ('name', 'color') ---- Remove this line of code
    filterset_class = PurchaseFilter</b>



注意
我不确定这一行,

qs = qs.filter(date__month__range=self.get_quarter_range(quarter))

但是,这就是在这种特殊情况下您需要进行过滤的方式。

希望这有帮助!!

关于django - 创建自定义过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53078788/

相关文章:

python - get_current_language_bidi 未按预期工作

python - Django / python : group results by time slots

python - Django DecimalField 在保存时生成 "quantize result has too many digits for current context"错误

python - Django 主键序列化器 "This field may not be null"同时allow_null=True

python - 你能优化这段代码吗? ( Django , python )

python - 如何显示每个用户对用户对话的最后一条消息以保留聊天记录?

Django Rest Framework 在结果中随机返回空列表,但计数仍然正确

javascript - 如何从 Ajax POST 解析 Django View 中的 JSON 对象

python - Django - 如何使用 Django Rest Framework 按日期过滤?

Django DRF 创建用户