Django自定义管理模型视图

时间:2011-07-19 18:44:18

标签: python django django-admin

在我的Django应用程序中,我拥有为所有未注册用户创建的Guest个用户帐户(他们都有email='guest@mysite.com')。同时,我创建了一些与Guest帐户相关的演示对象。 这些对象与注册用户的对象位于同一个表中(具有相同的模型)。而且我有更多这类对象的类型(模型),如:

class Object1(models.Model):
    user = ForeignKey(...)
    ...

class Object2(models.Model):
    user = ForeignKey(...)
    ...

当我在 django admin 中查看来宾帐户时,我希望过滤掉与来宾帐户相关的所有对象。

现在我将django.contrib.admin.views.main.ChangeList子类化并覆盖get_query_set方法来执行必需的排除,并在运行时重新定义django的ModelAdmin类的get_changelist方法:

class FilteredChangeList(ChangeList):
    def get_query_set(self):
        qs = super(FilteredChangeList, self).get_query_set()
        if is_related_to(self.model, Profile):
            qs = qs.exclude(user__email='guest@mysite.com')
        return qs

def my_getchangelist(self, request, **kwargs):
    return FilteredChangeList

ModelAdmin.get_changelist = my_getchangelist

我想在运行时重新定义django的方法是一种不好的做法,那么这个问题有没有正确的解决方案呢?

3 个答案:

答案 0 :(得分:4)

猜猜你做的工作多于必要的工作。您还可以创建自己的ModelAdmin类并覆盖其queryset方法,无需构建自己的ChangeList类:

class MyFilteredAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(MyFilteredAdmin, self).queryset(request)
        if is_related_to(self.model, Profile):
            qs = qs.exclude(user__email='guest@mysite.com')
        return qs

然后,您可以直接使用这个新的管理类注册模型 - admin.site.register(Model, MyFilteredAdmin) - 或创建从MyFilteredAdmin继承的子类,而不是django的ModelAdmin

答案 1 :(得分:2)

您也可以拥有代理模型。您可以拥有一个拥有“真正”用户的用户,以及一个拥有“访客”用户的用户。

答案 2 :(得分:1)

您可以继承ModelAdmin并覆盖get_changelist方法,而不是在运行时重新定义。

class FilteredModelAdmin(ModelAdmin):
    def get_changelist(self, request, **kwargs):
        return FilteredChangeList

然后使用FilteredModelAdmin而不是ModelAdmin注册您的模型。

admin.site.register(Object1, FilteredModelAdmin)
admin.site.register(Object2, FilteredModelAdmin)

如果您需要为模型子类FilteredModelAdmin而不是ModelAdmin自定义任何其他设置。

class Object1ModelAdmin(FilteredModelAdmin)
    # other customizations here

admin.site.register(Object1, Object1ModelAdmin)