Django 管理员模型继承是否可能?

7 投票
6 回答
11762 浏览
提问于 2025-04-17 02:01

在管理模型中可以使用继承吗?

比如说,考虑以下内容:

文件:models.py

class AbstractModel ( models.Model ):
    # Meta Information common to all classes
    author = models.ForeignKey(auth.models.User , null = False ,related_name="%(class)s_related_author" ) # The user who created 
    editor = models.ForeignKey(auth.models.User , null = True,related_name="%(class)s_related_editor" ) # The user who last edited                   
    created_at = models.DateTimeField(auto_now_add  = True) # Create Time
    edited_at = models.DateTimeField(auto_now = True) # Modify Time

    class Meta:
                abstract = True


class Topic( AbstractModel ):
    name = models.CharField(max_length = NameMaxLength , unique = True)
    version_number = models.IntegerField(default = 0)
    update_frequency = models.IntegerField()

ModelAdmin中使用类似的继承似乎没有产生正确的结果。

文件:admin.py

class Abstract_Admin_Model( admin.ModelAdmin ):
        fields =  ('author' , 'editor' , 'created_at' , 'edited_at')
        readonly_fields = ('author' , 'editor' , 'created_at' , 'edited_at')

        def save_model(self, request, obj, form, change):
                if not change :
                        obj.author = request.user
                else : 
                        obj.editor = request.user
                obj.save()

class Admin_Topic( Abstract_Admin_Model ):
     fields += ('name' , 'version_number' , 'update_frequency')


admin.site.register( Topic , Admin_Topic )

编辑:

我根据建议修改了上面的模型,

如果admin.py是这样写的,我没有遇到任何错误,模型也出现在管理界面上。

class AbstractAdminModel(  admin.ModelAdmin  ):
        pass#fields = ['author' , 'editor' , 'created_at' , 'edited_at']


class Admin_Topic( AbstractAdminModel ):
    pass

admin.site.register( Topic , Admin_Topic )

但是如果我这样修改:

class AbstractAdminModel(  admin.ModelAdmin  ):
    fields = ['author' , 'editor' , 'created_at' , 'edited_at']


class Admin_Topic( AbstractAdminModel ):
    pass

admin.site.register( Topic , Admin_Topic )

我就会遇到以下错误:

错误信息

这里有一个堆栈跟踪的链接 链接

问题:模型甚至没有出现在管理页面上。

额外信息:

使用的是django 1.2.5,pinax 0.7.2,Ubuntu 11.04,python 2.7.1+

6 个回答

3

要使用父类的属性,比如 list_displaysearch_fields,你可以这样做:

@admin.register(BaseClass)
class BaseClassAdmin(admin.ModelAdmin):
    list_display = ('field_a', 'field_b')
    search_fields = ('field_a', 'field_b')

@admin.register(ChildClass)
class ChildClassAdmin(BaseClassAdmin):
    def get_list_display(self, request):
        return self.list_display + ('field_c', 'field_d')

    def get_search_fields(self, request):
        return self.search_fields + ('field_c', 'field_d')

同样,你也可以对其他属性进行类似的操作,比如 actionsreadonly_fields 等等。

4

是的,这是可能的。我觉得你犯的错误是把:

class Meta:
    abstract = True

放在了你的 Abstract_Admin_Model 类里面。试着去掉 Meta 类看看。

8

也许你现在看到这个答案有点晚了,但我觉得其他人可能也会遇到类似的问题,就像我当时一样。

这是我的解决办法——我不确定这是否是正确的做法,但对我来说有效,而上面提到的其他方法都不能做到这一点(假设你和我一样想要多表继承(非抽象模型))。

class SiteEntityAdmin(admin.ModelAdmin):
    fieldsets = [
            (None, {'fields': ['name']}),
    ]


class PhotoAdmin(SiteEntityAdmin):
    fieldsets = [
             ('Photo details', {'fields': ['photo_url', 'description']}),
    ]
    fieldsets.insert(0, SiteEntityAdmin.fieldsets[0])

撰写回答