python - Appropriate way to override Model __getattr__ in 1.4 -
what's appropriate way of overriding model class's getattr in django 1.4?
i have model structure like:
class main(models.model): [blah] class detail(models.model): main = models.foreignkey(main) name = models.charfield(max_length=255) value= models.charfield(max_length=255) i had overridden main.getattr_ reference detail records though normal main attributes. e.g. simple meta- model pattern like
>>> m = main.objects.create() >>> detail.objects.create(main=m, name='name', value='value') >>> print m.name 'value' to this, pre-1.4 getattr looked like:
def __getattr__(self, attrname): qs = self.details.filter(name=attrname) c = len(qs) if c == 0: raise attributeerror elif c == 1: return qs[0].value else: return [d.value d in qs] this worked until upgraded 1.4. types "attribute x not exist" errors. tried following, had no luck. seems conflict "_*_cache" attributes django generates foreignkey references.
def __getattr__(self, attrname): try: return super(main, self).__getattr__(attrname) except attributeerror: pass qs = self.details.filter(name=attrname) c = len(qs) if c == 0: raise attributeerror elif c == 1: return qs[0].value else: return [d.value d in qs] how resolve this?
digging through new model code, seems backend has been changed substantially, model class no longer has __getattr__ override. instead, need call object.__getattribute__, base model inherits from. however, django stores cached data in special attributes, need handled.
my new __getattr__ looks like:
def __getattr__(self, attrname): try: return super(main, self).__getattribute__(attrname) except attributeerror: if attrname.startswith('_prefetched'): raise qs = self.details.filter(name=attrname) c = len(qs) if c == 0: raise attributeerror elif c == 1: return qs[0].value else: return [d.value d in qs]
Comments
Post a Comment