Django 自定义 AdminModel 视图

dra*_*oon 2 python django django-admin

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

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

class Object2(models.Model):
    user = ForeignKey(...)
    ...
Run Code Online (Sandbox Code Playgroud)

我想要实现的是在django admin 中查看与访客帐户相关的所有对象时过滤掉它们。

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

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
Run Code Online (Sandbox Code Playgroud)

我认为在运行时重新定义 django 的方法是一种不好的做法,那么是否有针对该问题的正确解决方案?

Ber*_*ant 5

猜猜你做了很多不必要的工作。您也可以创建自己的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
Run Code Online (Sandbox Code Playgroud)

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