2012-10-25 51 views
0

我有一个模型(让我们称之为实体)具有随时间变化的属性(属性),但我想保留该属性在数据库中如何变化的历史记录。我需要能够通过其管理器中当前的属性值来过滤我的实体。但是因为Django(据我所知)不会让我在本地执行一个查询操作,所以我创建了一个数据库视图,为每个实体生成最新的属性值。所以我的模型结构看起来是这样的:在Django刷新模型的非托管相关模型

class Entity(models.Model): 
    def set_attribute(self, value): 
     self.attribute_history.create(value=value) 

    def is_attribute_positive(self, value): 
     return self.attribute.value > 0 

class AttributeEntry(models.Model): 
    entity = models.ForeignKey(Entity, related_name='attribute_history') 
    value = models.IntegerField() 
    time = models.DateTimeField(auto_now_add=True) 

class AttributeView(models.Model) 
    id = models.IntegerField(primary_key=True, db_column='id', 
     on_delete=models.DO_NOTHING) 
    entity = models.OneToOneField(Entity, related_name='attribute') 
    value = models.IntegerField() 
    time = models.DateTimeField() 

    class Meta: 
     managed = False 

我的数据库有一个产生电流的属性来看,有这样的SQL创建:

CREATE VIEW myapp_attributeview AS 
SELECT h1.* 
FROM myapp_attributehistory h1 
LEFT OUTER JOIN myapp_attributehistory h2 
    ON h1.entity_id = h2.entity_id 
     AND (h1.time < h2.time 
     OR h1.time = h2.time 
     AND h1.id < h2.id) 
WHERE h2.id IS NULL; 

我的问题是,如果我设置的属性使用set_attribute()检查模型对象is_attribute_positive()并不总是可行,因为Django可能会缓存相关的AttributeView对象。我该如何让Django更新其模型,至少通过重新查看视图?我可以将attribute属性标记为脏吗?

PS:我这样做的全部原因是我可以做像Entity.objects.filter(attribute__value__exact=...).filter(...)这样的事情,所以如果有人知道获得该功能的更简单的方法,那么这样的答案也将被接受!

回答

0

我从来没有直接解决了这个问题,但我可以通过改变is_attribute_positiive()直接查询数据库表回避,而不是认为它。

def is_attribute_positive(self, value): 
    return self.attribute_history.latest().value > 0 

因此,尽管认为给我的是能够对实体筛选查询的灵活性,它似乎做的最好的事情,一旦被接收的对象是直接放在桌子上支持的模式来运作。

0

我知道属性值被另一个进程修改(甚至可能不是Django)访问同一个数据库。如果不是这种情况,你应该看看django-reversion

另一方面,如果是这样的话,你应该看看this的第二个答案。它表示提交事务使查询缓存无效并提供此片段。

>>> from django.db import transaction 
>>> transaction.enter_transaction_management() 
>>> transaction.commit() # Whenever you want to see new data 
+0

该属性在视图底层的表中被修改。问题是Django不知道该模型是由视图支持的,所以它没有理由重新查询。您提供的链接对我的情况没有帮助,因为我实际上正在执行集合并检入实体本身的方法,因此我没有明显的方式请求新的查询集以获取self.attribute – acjay