2017-10-12 51 views
0

有时,我们会保存一些更改为Redis或其他后端的字段。如何将非数据库自动属性设置为Django模型实例

但是这样,我们可能会失去从article.count获取实例值的便利。

我们通常将属性函数设置为模型,该模型执行查询基于内存的数据库的逻辑。

class WhatEver(models.Model): 
    @property 
    def some_field(self): 
     return redis.hget('what-ever-%s' % self.id) 

    def set_some_field(self, value): 
     return redis.hset('what-ever-%s' % self.id, value) 

丑,但有用。

但是,它并不是一直工作,因为它是一种侵入性的方式给我们带来能力。

说,我们希望得到一个用户的访问,

实际上,我们想打电话user.visits

但它不是很好的一个子模块覆盖基本模块,所以我们只能把它包装成一个功能get_user_visits(user),再次,不优雅。

我们是否有办法自动和非侵入地完成这种技巧?

回答

0

最后,没有现有的解决方案可以解决我的需求。

我已经实现了它和开源:django-in-memory-models

它可以通过pip install django-in-memory-models

1

要设置该值,您必须在实例级别执行此操作。因此,无论是通过在模型中创建自定义方法,还是仔细使用信号,都可以完成。

对于获取结果,您可以使用自定义管理器和custom method on the manager修饰模型的返回值。

from django.db import models 

class RedisManager(models.Manager): 
    def visits(self): 
     results = [] 
     for obj in self.model.get_query_set().all(): 
      obj.visits = redis.hget('what-ever-%s' % obj.id) 
      results.append(obj) 
     return results 

class SomeModelNeedsVisits(models.Model): 
    objects = RedisManager() 
    # your normal fields here 

for obj in SomeModelNeedsVisits.objects.visits(): 
     print(obj.visits) 
+0

谢谢您的回答安装。有没有一种方法可以使用Django的ORM机制,但不能用'overwrite'或'monkey patch'模块? “假”一个模型会更好吗? – Cai

+0

我向你描述的既不是覆盖也不是猴子修补。这是文档中描述的用自定义功能丰富ORM的方式。 –

+0

是的。但它需要更改Model类中分配的'objects'?据我所知,它不能从'instance.visits'这样的实例中调用,除非覆盖或修补原始模块。 – Cai

相关问题