我有一个关于如何在启动模型实例时动态设置模型属性的问题。
我正在使用一个带有本机PostgreSQL JSONField的简单模型:
from django.db import models
from django.contrib.postgres.fields import JSONField
class Booking(models.Model):
data = JSONField(blank=False, encoder=DjangoJSONEncoder)
有没有办法根据存储在'数据中的值设置模型实例上的属性?模型实例化时的字段?
我希望能够做到这一点:
from .models import Booking
b = Booking.objects.create(data={'foo':'bar'})
b.foo # this should yield 'bar'
我最初的想法是覆盖模型的 init 方法,并使用setattr()设置实例属性,但覆盖模型的 init 在Django文档中强烈建议不要使用该方法。
还有其他方法可以达到这个目的吗?任何帮助表示赞赏。
PS:我知道我可以访问存储在'数据'中的值在这样的模型实例上:booking.data [' foo'],所以这不是我要找的。 p>
答案 0 :(得分:0)
如果您真的想这样做,可以覆盖getattr
方法。
class Booking(models.Model):
def __getattr__(self, attr):
if attr in self.data:
return self.data[attr]
else:
return super(Booking, self).__getattr__(attr)
答案 1 :(得分:0)
您可以在模型中简单地实现__getattr__
挂钩,即:
class Booking(models.Model):
# ...
def __getattr__(self, name):
try:
return self.data[name]
except KeyError:
try:
return super(Boooking, self).__getattr__(name)
except AttributeError:
raise AttributeError(
"object %s has no attribute '%s'" % (type(self).__name__, name)
)
但除非您确信您的json内容将始终具有相同的结构,我建议不要使用它 - 使用普通instance.data[key]
语法更明确。