Python 覆盖1.4中模型的适当方法
重写模型类的 Django 1.4中的getattr 我的模型结构如下:Python 覆盖1.4中模型的适当方法,python,django,django-models,Python,Django,Django Models,重写模型类的 Django 1.4中的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) 我已经重写了Main.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)
我已经重写了Main.getattr,因此可以引用详细信息
记录,就好像它们是正常的主属性一样。e、 g.一个简单的元数据-
模型样
>>> 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引用生成的“*\u缓存”属性
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]
我如何解决这个问题 通过挖掘新的模型代码,似乎后端已经发生了实质性的更改,因此模型类不再有要覆盖的
\uuuuu getattr\uuuuu
。相反,我需要调用基本模型从中继承的对象。但是,Django将缓存的数据存储在特殊属性中,需要正确处理这些属性
我的新\uuu getattr\uuuu
现在看起来像:
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 for d in qs]
我还没试过这个,但可能有用:
class Main(models.Model):
def __getattribute__(self, attrname):
try:
return super(Main, self).__getattribute__(attrname)
except AttributeError:
try:
return self.__getattr__(attrname)
except AttributeError:
# do your database accessing
但正如克里斯·普拉特所说,这一点效率都不高。你可能想考虑缓存你的属性。这是一个停下来问问题的好时机:为什么H-E-Houth-Hook-Boo棒在这么做?它不仅看起来像一个肮脏的黑客,而且效率极低,每次访问实例上的属性时都会生成一个数据库查询。你甚至没有缓存任何东西。不可否认,我的情况不同寻常。简单地说,我的模型允许用户定义自己的自定义模型。缓存很容易添加,为了简单起见,我省略了它。getattr(self,name)
将调用self.\uu getattribute\uuuu(name)
,导致无限递归。这会导致运行时错误:超过最大递归深度。