Django admin:排序/排序动态readonly_fields

时间:2012-11-24 13:01:01

标签: django sorting admin

如何排序/订购readonly_fields(参见https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields)?

这就是我的所作所为:

class MyUserAdmin(UserAdmin):
    readonly_fields = ('pinCount')
    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active', 'date_joined', 'last_login', 'pinCount')

    def pinCount(self, instance):
        return Pin.objects.filter(user=instance).count()

admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

在管理员中,应该可以通过pinCount对列表进行排序。由于它不是直接的数据库字段,因此根据文档不可能。有没有办法做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:0)

排序由数据库完成,而不是由管理员完成(这是更改列表上的调试工具栏输出):

enter image description here

这就是您无法使用自定义管理方法进行排序的原因。您可以通过覆盖ModeAdmin.queryset method向管理员的查询集添加Count注释:

class MyModelAdmin(admin.ModelAdmin):

    ...

    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return qs \
            .annotate(pin_count=Count('pin')) \
            .order_by('-pin_count')

或者如果您需要更多控制权,可以尝试sort the queryset displayed by the admin,但我没有对此进行测试:

class MyModel(models.Model):
    ...

    @property
    def pin_count(self):
        return self.pin.count()


import operator  
class MyModelAdmin(admin.ModelAdmin):

    ...

    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        return sorted(qs, key=operator.attrgetter('pin_count'))

答案 1 :(得分:0)

我自己没有这样做,但似乎有一些解决方案(一个可以为有问题的模型定义自定义ModelManager,另一个依赖于管理界面魔术的解决方案): Django admin: how to sort by one of the custom list_display fields that has no database field

您的案例中的问题是所讨论的模型是用户模型,这可能不是一个改变的好主意。在您的情况下,我建议添加自定义UserProfile模型,如下所述: Django user profile

如果您需要经常查询此值,我建议您为用户个人资料模型中的每个用户实现pinCount值。根据您的要求,您可以使用数据库触发器来更新此值。