Django - why can't I access dynamically-generated attributes in classes in my models.py from admin.py? -



Django - why can't I access dynamically-generated attributes in classes in my models.py from admin.py? -

here models.py:

class parent(models.model): id = models.charfield(max_length=14, primary_key=true) json_dump = models.textfield(null=false) def __init__(self, *args, **kwargs): super(base, self).__init__(*args, **kwargs) setattr(self, 'name', json.loads(self.json_dump)['name']) class meta: abstract = true class child(parent): magnitude = models.integerfield()

in admin.py configure admin kid have name attribute displayed, have following:

class childadmin(admin.modeladmin): model = kid def get_list_display(self, request): homecoming ('id', 'name', 'magnitude') admin.site.register(child, childadmin)

i have have list_display generated on fly get_list_display method because otherwise django throws error on startup complaining name not defined in child model. however, when running, name should available set in __init__ method whenever object instantiated database.

however, when seek load admin page error:

unable lookup 'name' on kid or childadmin

what gives?

<class 'app.admin.childadmin'>: (admin.e108) value of 'list_display[1]' refers 'name', not callable, attribute of 'childadmin', or attribute or method on 'app.child'.

the above more error message receiving. abstract classes not allow inherit instance attributes abstract class that. looking self.name on kid class, not exist.

the parts of error want @ is:

...which not callable

nope. not callable, attribute.

...an attribute of 'childadmin',

nope. isn't attribute of childadmin class.

...or attribute or method on 'app.child'.

this part tripping up. "what gives" isn't attribute or method of child class, parent class.

what want is:

class parent(models.model): id = models.charfield(max_length=14, primary_key=true) json_dump = models.textfield(null=false) class meta: abstract = true @property def name(self): homecoming json.loads(self.json_dump)['name'] class child(parent): magnitude = models.integerfield()

doing create attribute available child class parent. alternatively, instead of using @property decorator, create function definition called get_name. find first simpler.

the caveat method not save name @ runtime. if want that, may want consider django's signals post_save hook retrieve name value , add together name = models.charfield(...) model.

for clarification, django not back upwards this. on startup, next code runs check on list_display property:

def _check_list_display_item(self, cls, model, item, label): """ cls=<class 'app.admin.childadmin'> model=<class 'app.models.child'> item='name' """ # 'name' not callable if callable(item): homecoming [] # <class 'app.admin.childadmin'> not have class attribute 'name' elif hasattr(cls, item): homecoming [] # <class 'app.models.child'> not have class attribute 'name' elif hasattr(model, item): ... else: try: # <class 'app.models.child'>.meta not have field called 'name' model._meta.get_field(item) except models.fielddoesnotexist: # end up. homecoming [ # deliberate repeat of e108; there's more 1 path # required test condition. checks.error( "the value of '%s' refers '%s', not callable, attribute of '%s', or attribute or method on '%s.%s'." % ( label, item, cls.__name__, model._meta.app_label, model._meta.object_name ), hint=none, obj=cls, id='admin.e108', ) ]

as can see, have added comments code run help understand happening. right instance of child have name, isn't django looking for. it's looking class attribute, not instance attribute.

so, way can tackle (you won't this, either) doing:

class parent(models.model): id = models.charfield(max_length=14, primary_key=true) json_dump = models.textfield(null=false) name = '' other_item = '' this_too = '' and_this = '' class meta: abstract = true def __init__(self, *args, **kwargs): super(parent, self).__init__(*args, **kwargs) setattr(self, 'name', json.loads(self.json_dump)['name']) setattr(self, 'other_item', json.loads(self.json_dump)['other_item']) setattr(self, 'this_too', json.loads(self.json_dump)['this_too']) setattr(self, 'and_this', json.loads(self.json_dump)['and_this'])

this works. tested it. django find attribute on class.

django django-models django-admin django-1.7

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -