django admin list_filter外键子集

时间:2012-01-26 01:15:56

标签: django django-admin django-admin-filters

我目前的模型设置如下:

我有一个Test类,其中包含自定义UserProfile类的外键。此属性称为student。因此,每个UserProfile可能需要多个Test。然后,每个UserProfile通过典型的onetoone关系绑定到User。添加了另一个复杂程度,因为我已声明了两个用户组tutorsstudents。并且UserProfile类与自己标记为"导师"有一个ManyToMany关系。逻辑是每个学生可能有很多辅导老师教他。现在我想要做的是在Test管理页面的右侧添加过滤器,让您可以按学生过滤,也可以按导师过滤。设置list_filter = ('student',)只列出所有可用的UserProfiles。但这包括与导师相关的UserProfiles。显然,我想将这个列表过滤到只有学生,因为任何这些导师明显过滤都会导致一个空的查询集。然后我想通过导师过滤做类似的事情,在这种情况下,速记将是list_filter = ('student__tutors'),但我希望将此UserProfile集过滤到仅包含user_ 基 _name ='导师&#39 ;.这样做的最佳方式是什么?

为清楚起见,我的对象模型如下所示:

class UserProfile(models.Model):
    user = models.OneToOneField(User, unique=True,related_name='profile')
    tutors = models.ManyToManyField("self",related_name="students")
class Test(models.Model):
    student = models.ForeignKey(UserProfile,related_name='tests')

我尝试使用以下内容对django.contrib.admin.SimpleListFilter进行子类化:

class StudentListFilter(SimpleListFilter):
    title = 'student'
    parameter_name = 'student__id__exact'
    def lookups(self, request, model_admin):
        qs = model_admin.queryset(request)
        return User.objects.filter(profile__id__in=qs.values_list('student__id')).extra(select={'full_name':'first_name||" "||last_name'}).values_list('profile__id','full_name')

    def queryset(self, request, queryset):
        if self.value() is not None:
            return queryset.filter(student__id__exact=self.value())
        else:
            return queryset

这似乎适用于第一个list_filter,但问题是出于某种原因现在出现了一个错误,即所选选项未在自定义过滤器中突出显示。只有'全部'突出显示但不是自定义选项。以下是另一位用户发布的示例:

http://imgur.com/lyrYk

我目前正在使用django 1.4的开发版本,所以我不确定这个问题是否与此有关。

1 个答案:

答案 0 :(得分:2)

有趣的问题。

我认为您需要将lookups转换为字符串。

return [(str(x), y) for x, y in your_valuesqueryset]

django.admin.filters上的第98行将所选过滤器定义为:

'selected': self.value() == lookup

直接从lookups方法的结果填充查找。

filter()来电中的自动类型强制使过滤器成功,但'2' != 2