Django自定义FilterSet

需求:根据时间范围过滤数据

实现

1、定义FilterSet

import rest_framework_filters as filters

class TimeFilterSet:
    """根据时间范围过滤"""
    filter_map = {
        'Date': django_filters.DateFilter,
        'Time': django_filters.DateTimeFilter,
        'DateTime': django_filters.DateTimeFilter
    }

    @classmethod
    def build_filter_class(cls, _model, field='create_time', field_type='DateTime', filter_fields=()):
        filter_class = cls.filter_map[field_type]

        class TimeFilter(django_filters.FilterSet):
            start_time = filter_class(field_name=field, lookup_expr='gte')
            end_time = filter_class(field_name=field, lookup_expr='lt')

            class Meta:
                model = _model
                fields = filter_fields
        return TimeFilter

2、settings配置

配置'django_filters.rest_framework.DjangoFilterBackend'
REST_FRAMEWORK = {
    'DATETIME_FORMAT': '%Y-%m-%d %H:%M:%S',
    'DEFAULT_PAGINATION_CLASS': 'itom_cmdb.libs.frameworks.pagination.ItomPageNumberPagination',
    'DEFAULT_AUTHENTICATION_CLASSES': [
    ],
    'DEFAULT_FILTER_BACKENDS': [
        'rest_framework_filters.backends.RestFrameworkFilterBackend',
        'rest_framework.filters.SearchFilter',
        'rest_framework.filters.OrderingFilter',
    ],

}

3、view中调用

class Record(models.Model):
    class ActionType(models.TextChoices):
        ADDITION = 'ADDITION', _('添加')
        CHANGE = 'CHANGE', _('修改')
        DELETION = 'DELETION', _('删除')

    user_id = models.CharField(max_length=64, null=True, verbose_name=_('用户ID'))
    username = models.CharField(max_length=128, null=True, verbose_name=_('用户姓名'))
    content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL, verbose_name=_('内容类型'))
    object_id = models.CharField(max_length=64, null=True, verbose_name=_('对象ID'))
    object_repr = models.CharField(max_length=200, null=True, verbose_name=_('对象表示'))
    content = models.TextField(null=True, verbose_name=_('变更内容'))
    address = models.CharField(max_length=128, blank=True, null=True, verbose_name=_("IP地址"))
    action = models.CharField(max_length=16, choices=ActionType.choices, verbose_name=_('动作类型'))
    action_time = models.DateTimeField(auto_now_add=True, editable=False, verbose_name=_('动作时间'))
    comment = models.TextField(null=True, verbose_name=_('备注'))


class RecordViewSet(ModelViewSet):
    filter_fields = ('content_type__app_label', 'content_type__model', 'object_id')
    search_fields = filter_fields
    filter_class = TimeFilterSet.build_filter_class(Record, 'action_time', 'DateTime', filter_fields)
    # 一旦指定了filter_class,filter_fields就失效了,所以采用build_filter_class这种方式

    queryset = Record.objects.all()
    serializer_class = RecordSerializer

4、前端过滤

 127.0.0.1:8080/record/records/?start_time=2021-12-08 15:42:27&end_time=2021-12-10 15:42:27      

或:

127.0.0.1:8080/record/records/?start_time=2021-12-08&end_time=2021-12-09

不传具体时间时,默认为00:00:00

也可仅传开始或结束时间:

127.0.0.1:8080/record/records/?start_time=2021-12-08

5、django-filter自带的Filter

django-filter内置了丰富的Filter,包括上面提到了时间范围过滤,有兴趣可以研究一下。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值