gpt4 book ai didi

python - 使用 __getattr__ 更改 Django 模型的行为

转载 作者:太空狗 更新时间:2023-10-30 00:46:53 25 4
gpt4 key购买 nike

我正在尝试更改 Django 模型的行为以允许我直接从父项访问外键的属性,例如

cache.part_number  
vs
cache.product.part_number

我试过如下覆盖 __getattr__ 方法,但是当我尝试访问外键的属性时出现递归错误

class Product(models.Model):
part_number = models.CharField(max_length=10)
...

class Cache(models.Model):
product = models.ForeignKey(Product)
...

def __getattr__(self, name):
value = getattr(self.product, name, None)
if value:
return value
else:
raise AttributeError

我做错了什么?

最佳答案

考虑您的 __getattr__ 方法中的代码:

value = getattr(self.product, name, None)

尝试猜测调用 self.product 时会发生什么。我会给你一个线索:它涉及对 __getattr__ 的调用。 documentation有详细信息:

Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.

您是否想知道 self.product 如何解析为正确的 Product 实例,即使您没有在任何地方设置它?

Note that if the attribute is found through the normal mechanism, __getattr__() is not called.

Django 做了一些涉及拦截的魔法,您猜对了,__getattr__。因此 self 自动以属性 product 结束。由于您正在覆盖 __getattr__ 方法,Django 的魔力将停止工作并使用您的版本。由于 self.product 不是实例属性,__getattr__ 会被再次调用,如此反复,导致无限循环。

你最好使用 property实现这一目标。

class Cache(models.Model):
product = models.ForeignKey(Product)
...

def _get_part_number(self):
part_number = self.product.part_number
if not part_number:
raise AttributeError
return part_number
part_number = property(_get_part_number)

关于python - 使用 __getattr__ 更改 Django 模型的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3757951/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com