views:

25

answers:

2

I'm using some subclasses in my Django app, and I'm continuing that logic through to my admin implementation.

Currently, I have this admin defintion:

class StellarObjectAdmin(admin.ModelAdmin):
  list_display = ('title','created_at','created_by','updated_at','updated_by)

Now, I have a Planet class, that is a subclass of StellarObject, with an additional field. I want to add this field to the list_display (not replace StellarObject's display entirely).

If I try something like this:

class PlanetAdmin(StellarObjectAdmin):
  list_display.insert(1,'size')

I get the following error:

name 'list_display' is not defined

I will admit, I'm very new to python, and inheritance in general, so I'm sure that there is something simple I am missing.

Thank you

+2  A: 

You'll need to use:

StellarObjectAdmin.list_display.insert(1, 'size')

Also, you'll need to change list_display from a tuple (which is immutable) to a list. Eg: list_display = [ ... ].

Finally, you'll probably be surprised by what happens: by inserting the item, you're going to be changing the list on StellarObjectAdmin. What you probably want to do is:

list_display = list(StellarObjectAdmin.list_display) # copy the list
list_display.insert(1, 'size')

Which will create a new copy of the list for your PlanetAdmin class.

This happens because of the way Python does inheritance. Basically, Python never injects names into a namespace (eg, some languages inject a magic this "variable" into methods, while Python forces you to explicitly define the equivalent — self — as the first argument of methods), and since a class is just another namespace, nothing (like, eg, values in its super classes) gets injected into it.

When you've got a class, B, which inherits from another class, A, and you try to look up a property on BB.foo — it first checks to see if foo is in B's namespace, and if it isn't, it goes on to check A's namespace, and so on.

I hope that's clear… If not, I can clarify (or try to find relevant documentation).

David Wolever
+1  A: 

David is spot on. Also, as a note, if you want to reference the variable within the class, you'll need to use 'self.'

Example:

Class A:
   mylist = [1,2,3]

   def display_list(self):
      for i in self.mylist:
           print i
kcunning