2017-10-12 5 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メカニズムを使用する方法はありますか?モジュールを '上書きする'や 'monkey patch'はできませんか?モデルを「偽造する」方が良いでしょうか? – Cai

+0

私があなたに書いたことは、上書きもサルのパッチもないことです。マニュアルで説明されている方法で、カスタム機能でORMを充実させる方法です。 –

+0

はい、そうです。しかし、それはModelクラスで割り当てられた 'objects'を変更する必要がありますか?私が知っているように、元のモジュールに上書きしたりパッチを当てたりしない限り、 'instance.visits'のようなインスタンスから呼び出すことはできません。 – Cai

関連する問題