Dav*_*Eyk 14 python django memoization django-models
我的UserProfile对象上有几个包含JSON对象的TextField列.我还为每个列定义了一个setter/getter属性,它封装了将JSON序列化和反序列化为python数据结构的逻辑.
此数据的性质可确保在单个请求中通过视图和模板逻辑多次访问它.为了节省反序列化成本,我想在读取时记住python数据结构,在直接写入属性时无效或从模型对象保存信号.
在哪里/如何存储备忘录?我对使用实例变量感到紧张,因为我不理解查询实例化任何特定UserProfile背后的魔力.是__init__使用安全,或是否需要通过检查备忘录属性的存在hasattr(),在每个读?
这是我当前实现的一个示例:
class UserProfile(Model):
text_json = models.TextField(default=text_defaults)
@property
def text(self):
if not hasattr(self, "text_memo"):
self.text_memo = None
self.text_memo = self.text_memo or simplejson.loads(self.text_json)
return self.text_memo
@text.setter
def text(self, value=None):
self.text_memo = None
self.text_json = simplejson.dumps(value)
Run Code Online (Sandbox Code Playgroud)
sat*_*oru 24
您可能对内置的django装饰器感兴趣django.utils.functional.memoize.
Django使用它来缓存昂贵的操作,如url解析.
Dan*_*man 18
一般来说,我使用这样的模式:
def get_expensive_operation(self):
if not hasattr(self, '_expensive_operation'):
self._expensive_operation = self.expensive_operation()
return self._expensive_operation
Run Code Online (Sandbox Code Playgroud)
然后使用该get_expensive_operation方法访问数据.
但是,在您的特定情况下,我认为您正在以一种错误的方式接近这一点.首次从数据库加载模型时需要进行反序列化,并且仅在保存时进行序列化.然后,您每次只需将属性作为标准Python字典进行访问即可.您可以通过定义自定义JSONField类型,子类化models.TextField来覆盖to_python和执行此操作get_db_prep_save.
事实上有人已经做到了:看到这里.