在Django/Python中向继承列表插入额外项
我在我的Django应用中使用了一些子类,并且我想把这个逻辑继续应用到我的管理界面上。
现在,我有这样的管理定义:
class StellarObjectAdmin(admin.ModelAdmin):
list_display = ('title','created_at','created_by','updated_at','updated_by)
我有一个叫做Planet的类,它是StellarObject的子类,并且多了一个字段。我想把这个字段添加到列表显示中(而不是完全替换掉StellarObject的显示)。
如果我尝试这样做:
class PlanetAdmin(StellarObjectAdmin):
list_display.insert(1,'size')
我就会遇到以下错误:
name 'list_display' is not defined
我承认,我对Python和继承的概念还很陌生,所以我肯定有一些简单的地方没有理解。
谢谢!
2 个回答
1
大卫说得很对。另外,值得注意的是,如果你想在类里面引用某个变量,你需要用上 'self.' 这个前缀。
举个例子:
Class A:
mylist = [1,2,3]
def display_list(self):
for i in self.mylist:
print i
2
你需要使用:
StellarObjectAdmin.list_display.insert(1, 'size')
另外,你需要把 list_display
从一个 tuple
(这是一种不可变的类型)改成一个 list
。比如说:list_display = [ ... ]
。
最后,你可能会对接下来发生的事情感到惊讶:当你插入这个项目时,你实际上是在改变 StellarObjectAdmin
上的列表。你可能想要做的是:
list_display = list(StellarObjectAdmin.list_display) # copy the list
list_display.insert(1, 'size')
这样会为你的 PlanetAdmin
类创建一个新的列表副本。
之所以会这样,是因为 Python 的继承方式。简单来说,Python 不会自动把名字放进命名空间(比如,有些语言会在方法中自动注入一个神奇的 this
“变量”,而 Python 要求你明确地把相应的内容 — self
— 作为方法的第一个参数),而且因为 class
只是另一个命名空间,所以没有任何东西(比如它的父类中的值)会被自动注入。
当你有一个类 B
,它继承自另一个类 A
,如果你想在 B
上查找一个属性 B.foo
,它会先检查 foo
是否在 B
的命名空间里,如果没有,就会去检查 A
的命名空间,依此类推。
希望这样说清楚了……如果不清楚,我可以再解释一下(或者试着找相关的文档)。