Django Admin list_filter 和带注释字段的排序

标签 django django-models django-admin

我正尝试在 Django Admin 中过滤带注释的字段,但出现 FieldDoesNotExist 错误。

class Event(models.Model):
    name = models.CharField(max_length=50, blank=True)

class EventSession(models.Model):
    event = models.ForeignKey(Event, on_delete=models.CASCADE)
    start_date = models.DateTimeField()
    end_date = models.DateTimeField()


@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    ordering = ["event_start_date"]
    list_filter = ["event_start_date", "event_end_date"]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        qs = qs.annotate(
            event_start_date=Min("eventsession_set__start_date"), # start of first day
            event_end_date=Max("eventsession_set__start_date"), # start of last day
        )
        return qs

在 Django Admin 中产生的错误是:

FieldDoesNotExist at /admin/events/event/
Event has no field named 'event_start_date'

我需要根据 event_start_date 而不是 eventsession_set__start_date 进行过滤,因为 filtering ordering (edit) 后者会导致每个事件的多个行(每个 session 一个)显示在 ListView 中。

错误来自 get_field method django/db/models/options.py:

    try:
        # Retrieve field instance by name from cached or just-computed
        # field map.
        return self.fields_map[field_name]
    except KeyError:
        raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))

我正在使用 Django 3.2。有什么想法吗?

最佳答案

这是一个示例,说明如何在 django 管理列表页面添加排序和按带注释的字段进行过滤

class EventStartDateListFilter(admin.SimpleListFilter):
    title = "start_date"
    parameter_name = "start_date"

    def lookups(self, request, model_admin):
        return (
            ("week", "week"),
            # add other filters
        )

    def queryset(self, request, queryset):
        value = self.value()
        if value == "week":
            return queryset.filter(_event_start_date__gt=now() - timedelta(weeks=1))
    
        return queryset

@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    list_display = ["__str__", "event_start_date", "event_end_date"]

    ordering = ["event_start_date", "event_end_date"]
    list_filter = [EventStartDateListFilter]


    def event_start_date(self, obj):
       return obj._event_start_date

    event_start_date.admin_order_field = '_event_start_date'

    def event_end_date(self, obj):
        return obj._event_end_date

    event_end_date.admin_order_field = '_event_end_date'

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        qs = qs.annotate(
            _event_start_date=Min("eventsession_set__start_date"), # start of first day
            _event_end_date=Max("eventsession_set__start_date"), # start of last day
        )
        return qs

关于Django Admin list_filter 和带注释字段的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68047139/

相关文章:

python - MySQL: django.db.utils.OperationalError: (1698, "Access denied for user ' root' @'localhost' ") with correct username and pw

django - 在 Django 中渲染 {{ var }} 和 {{ var|safe }} 的区别

django - 返回模型常见查询的最 Django 式方式

django - 使用 Django Rest Framework 时在哪里执行附加操作

python - 管理员中的 "Caught ImportError while rendering: No module named urls"

Django:如何获取与单行相关的所有行的总和

django - 当所有公共(public)访问都被阻止时,为什么我无法从我的 S3 存储桶中获取图像? 403 Forbidden 但静态文件加载正常

django - 如何根据当前对象字段值显示不同的内联

python - Django 管理员自定义选择表单字段选择

django - 虚拟环境 : cannot access lib: No such virtualenv or site directory