在 Django 管理中按自定义列表显示字段进行列表筛选

list filter by custom list display field in django admin

提问人:Vijay 提问时间:9/21/2015 最后编辑:Vijay 更新时间:7/13/2023 访问量:3879

问:

我有以下模型管理员。我在列表视图中显示自定义字段。

class CustomerAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email', 'state')
    search_fields = ('first_name', 'last_name', 'email')
    list_filter = ('state',)
    def state(self, obj):
        address = Address.objects.filter(owner=obj.id)
        if address:
            return address.state
    return None

我在上面尝试过,但它给出了一个错误“list_filter[0]”指的是'状态',而不是引用字段。 因此,我想按状态过滤记录。那么我如何在 django 1.5 中做到这一点呢?

python django django-admin

评论


答:

-4赞 varad 9/22/2015 #1
class CustomerAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name', 'email', 'state')
list_filter = ('state',)
search_fields = ('first_name', 'last_name', 'email')

def state(self, obj):
    address = Address.objects.filter(owner=obj.id)
    if address:
        return address.state
return None

如果要进行筛选,则应包含list_filter

评论

6赞 Vijay 9/23/2015
这不适用于自定义字段。它给出了一个错误CustomerAdmin.list_filter[0]“指的是”状态“,而不是引用字段。因为 state 不是 Customer 模型中的字段,并且 Address 模型和 Customer 模型之间也没有关系。
0赞 Nikita Sysoev 6/9/2023 #2

不幸的是,这是不可能的。在 中,当收集筛选字段时发生以下情况:django.admin.views

if not isinstance(field, Field):
   field_path = field
   field = get_fields_from_path(self.model, field_path)[-1]

所以,不是一个实例,而是一个返回字符串或 None 的函数。然后,正如你所看到的,Django 试图添加字段,假设它不是一个实例,但可以是模型字段的路径。 最终,它添加到 ,然后转到 检索字段的实例。stateFieldlist_filterFieldstatelist_filterdjango.db.models.options.Options

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 在模型中看不到这个字段,并抛出一个 Exception。此异常由 处理,它将错误消息转换为django.core.management.base.BaseCommand"list_filter[0]' refers to 'state' which does not refer to a Field."

0赞 Vitalii Korniichuk 6/14/2023 #3

list_filter适用于相关模型。

如果模型如下所示:

class Address(models.Model):
    owner = models.OneToOneField(Customer, models.CASCADE,
                             related_name='address')
    state = models.CharField(max_length=20)

您可以在 ModelAdmin 中使用address__state。例如:

@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email', 'state')
    search_fields = ('first_name', 'last_name', 'email')
    list_filter = ('address__state', )

请注意,list_display不是这样工作的!