Django 1.4でModelクラスの getattrをオーバーライドする適切な方法は何ですか?
次のようなモデル構造があります。
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)
メインをオーバーライドしました。getattr _ を使用して、Detail レコードを通常の Main 属性であるかのように参照できました。たとえば、次のような単純なメタモデル パターン
>>> m = Main.objects.create()
>>> Detail.objects.create(main=m, name='name', value='value')
>>> print m.name
'value'
これを行うには、1.4 より前のgetattrは次のようになりました。
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 for d in qs]
1.4にアップグレードするまで、これは完全に機能しました。これで、すべてのタイプの「属性 X が存在しません」というエラーが表示されます。次のようなことを試しましたが、うまくいきませんでした。特に、Django が ForeignKey 参照用に生成する「_*_cache」属性と競合するようです。
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 for d in qs]
これを解決するにはどうすればよいですか?