Django - 继承UserAdmin来创建动态模板?

时间:2011-01-03 02:32:44

标签: python django django-admin

我不太确定如何说出我想问的问题。假设您有两个可能与用户关联的配置文件对象。其中只有一个是关联的(有一对一的映射),但它可能是两个可能的配置文件对象之一。我的管理员代码如下所示:

admin.site.unregister(User)

class AProfileInline(admin.StackedInline):
    model = UserProfileA

class BProfileInline(admin.StackedInline):
    model = UserProfileB

class UserProfileAdmin(UserAdmin):
    inlines = [AProfileInline, BProfileInline, ]

admin.site.register(User, UserProfileAdmin)

这可行,但当然会显示不必要的信息。如果管理页面只显示正确的内联,那将是很好的。我想这很复杂,如果我想从一种配置文件类型更改为另一种配置文件类型,则可能是一个问题。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

这是一种方法。请记住,这是一个黑客。我将此代码基于ModelAdmin中的django.contrib.admin.options代码。

admin.site.unregister(User)

class AProfileInline(admin.StackedInline):
    model = UserProfileA

class BProfileInline(admin.StackedInline):
    model = UserProfileB

class UserProfileAdmin(UserAdmin):
    inlines = [AProfileInline, BProfileInline, ]

    def get_object(self, *args, **kwargs):
        obj = super(UserProfileAdmin, self).get_object(*args, **kwargs)
        if obj:
            self.inline_instances = []
            if AProfileInline.model.objects.filter(user=obj):
                inline_instance = AProfileInline(self.model, self.admin_site)
                self.inline_instances.append(inline_instance) 
            if BProfileInline.model.objects.filter(user=obj):
                inline_instance = BProfileInline(self.model, self.admin_site)
                self.inline_instances.append(inline_instance)
        return obj

admin.site.register(User, UserProfileAdmin)

此解决方案假定UserProfileAUserProfileB都通过名为User的字段与user具有外键关系。

change_viewdelete_view函数调用get_object,因此在呈现这些视图之前,此代码应正确替换内联表单实例。

此代码会覆盖get_object以执行以下额外操作:

  1. 默认情况下,内联表单为空(对于预先存在的对象)
  2. 如果找到引用当前UserProfileA的{​​{1}}(通过User字段),则会添加user的内联表单。
  3. 如果找到引用当前UserProfileA的{​​{1}}(通过UserProfileB字段),则会添加User的内联表单。
  4. 此解决方案的怪癖:

    • user仍会创建UserProfileB的默认版本,只要使用UserProfileAdmin.__init__self.inline_instances,该版本就会被覆盖。
    • 此函数从未打算执行上述代码所使用的功能。如果在任何其他代码中调用change_view,则会不必要地重新计算内联表单。