使用UserProfile字段的Django 1.4 User Admin list_filter

时间:2013-10-04 17:10:31

标签: django django-admin-filters

编辑:我更新了代码以反映查询集过滤器中的一个错误,其中user_user_type已被替换为正确的userprofile__user_type。

我正在使用Django 1.4,我知道为管理员创建自定义list_filters有一个新功能,它取代了FilterSpec API。

我已经阅读了无数关于创建自定义管理list_filters的SO帖子,但我仍然卡住了。

我的用例是针对我的User对象的list_filter,它引用了UserProfile模型中的字段。

所以在models.py中:

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True)
    user_type = models.CharField(max_length=25, choices=USER_TYPES, default='Client')
    ...

并在admin.py中:

from django.contrib import admin
from django.contrib.admin import site, ModelAdmin, ChoicesFieldListFilter
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from models import UserProfile

class UserTypeFilter(ChoicesFieldListFilter):
    title = 'User Type'
    parameter_name = 'user_type'

    def lookups(self, request, model_admin):
        usertypes = set([c.user_type for c in UserProfile.objects.all()])
        return [(c.id, c.user_type) for c in usertypes]

    def queryset(self, request, queryset):
        if self.value():
            return queryset.filter(userprofile__user_type=self.value())
        else:
            return queryset

class UserAdmin(UserAdmin):
    list_filter = ('is_staff', UserTypeFilter)
    inlines = (UserProfileInline, )


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

这是我得到的错误:

'UserAdmin.list_filter[1]' is 'UserTypeFilter' which is of type FieldListFilter but is not associated with a field name.

我最初尝试使用SimpleListFilter,并收到此错误

'unicode' object has no attribute 'id'

这是有道理的,因为我的user_type字段是一个选择字段,选项是unicode对象。

文档显示了这个例子:

class PersonAdmin(UserAdmin):
    list_filter = ('company__name',)

但这似乎意味着“公司”是用户模型的一个领域。我是否需要重新定义我的用户模型以包含OneToOneField for UserProfile?或者我错过了一些引用用户个人资料的明显方法?

谢谢,

1 个答案:

答案 0 :(得分:3)

您引用的第一个错误似乎特定于我从未使用过的FieldListFilter。我想重点是自动化与特定领域相关的东西。

在你提供所有选项时,我认为没有用它。

我现在只使用SimpleListFilter ...

无论如何,您的错误是usertypes是一组c.user_type,这是一个字符串。它没有id属性。

您需要返回[(c, c) for c in usertypes],其中第一个值是传递给QS的值,第二个值是显示值。

其余的不需要改变。