如何使用自定义字段在Django Admin中实现日期范围过滤器?

2024-09-29 21:30:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在Django Admin中通过一个在模型中实际上不作为字段存在的值在模型上实现日期范围过滤。我想从django-admin-rangefilter包中使用类似the date range pickerDateRangeFilter

假设模型有date字段,我们希望显示对象,其中date - 7位于指定范围之间(只是一个人工示例)

我已经创建了一个自定义过滤器类

class CustomDateFilter(DateRangeFilter):
   title = "custom_date"

   def queryset(self, request, queryset):
       queryset = queryset.annotate(custom_date=F("date") - 7)
       if self.form.is_valid():
           validated_data = dict(self.form.cleaned_data.items())
           if validated_data:
               return queryset.filter(
                   **self._make_query_filter(request, validated_data)
                )
       return queryset

但是它的使用会导致FieldDoesNotExist ... 错误(如果使用它):

@admin.register(SomeModel)
class SomeModelAdmin(admin.ModelAdmin):
    list_filter = [("custom_date", CustomDateFilter)]

SystemCheckError: System check identified some issues:

ERRORS:
<class '...SomeModelAdmin'>: (admin.E114) The value of 'list_filter[0]' must not inherit from 'FieldListFilter'.

如果使用,则:

@admin.register(SomeModel)
class SomeModelAdmin(admin.ModelAdmin):
    list_filter = [CustomDateFilter]

我怎样才能实现我想做的事情


Tags: 模型selfdatadateadminrequestcustomfilter
1条回答
网友
1楼 · 发布于 2024-09-29 21:30:53

首先,您正在尝试:

queryset = queryset.annotate(custom_date=F("date") - 7)

这是错误的。日期是日期字段(Django默认日期格式:yyyy-mm-dd)。我们可以这样做:

from datetime import datetime, timedelta
queryset = queryset.annotate(custom_date=F("date") - timedelta(days=7))

您正在覆盖来自django-admin-rangefilter包的DateRangeFilter类的以下默认queryset方法

def queryset(self, request, queryset):
    if self.form.is_valid():
        validated_data = dict(self.form.cleaned_data.items())
        if validated_data:
            return queryset.filter(
                **self._make_query_filter(request, validated_data)
            )
    return queryset

似乎您正在尝试在筛选之后添加动态字段。尝试这样做:

queryset = queryset.annotate(custom_date=F("date") - timedelta(days=7))

在过滤之前

因此queryset方法类似于:

def queryset(self, request, queryset):
    from datetime import datetime, timedelta
    from django.db.models import DateField, F
    queryset = queryset.annotate(custom_date=F("date") - timedelta(days=7), output_field=DateField())
    if self.form.is_valid():
        validated_data = dict(self.form.cleaned_data.items())
        if validated_data:
            return queryset.filter(
                **self._make_query_filter(request, validated_data)
            )
    return queryset

相关问题 更多 >

    热门问题