需求:根据时间范围过滤数据
实现:
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,包括上面提到了时间范围过滤,有兴趣可以研究一下。