2017-10-12 53 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

相關問題