16

JSON オブジェクトを含む UserProfile オブジェクトにいくつかの TextField 列があります。JSON を Python データ構造にシリアライズおよびデシリアライズするためのロジックをカプセル化する、各列のセッター/ゲッター プロパティも定義しました。

このデータの性質により、単一のリクエスト内でビューおよびテンプレート ロジックによって何度もアクセスされることが保証されます。逆シリアル化のコストを節約するために、読み取り時にpythonデータ構造をメモ化し、プロパティへの直接書き込み時に無効にするか、モデルオブジェクトからの信号を保存したいと思います。

メモはどこにどのように保存しますか? 特定の UserProfile がクエリによってどのようにインスタンス化されるかの背後にある魔法を理解していないため、インスタンス変数の使用について神経質になっています。安全に使用できますか、または読み取りごと__init__に memo 属性の存在を確認する必要がありますか?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)
4

3 に答える 3

23

組み込みの django decorator に興味があるかもしれませんdjango.utils.functional.memoize

Django はこれを使用して、URL 解決などの高価な操作をキャッシュします。

于 2010-04-14T03:28:16.770 に答える
18

一般的に、私は次のようなパターンを使用します。

def get_expensive_operation(self):
    if not hasattr(self, '_expensive_operation'):
        self._expensive_operation = self.expensive_operation()
    return self._expensive_operation

次に、get_expensive_operationメソッドを使用してデータにアクセスします。

ただし、特定のケースでは、これに少し間違った方法でアプローチしていると思います。モデルがデータベースから最初に読み込まれるときに逆シリアル化を実行し、保存時にのみシリアル化する必要があります。その後、毎回、標準の Python 辞書として属性に簡単にアクセスできます。カスタムの JSONField タイプを定義し、models.TextField をサブクラス化してこれを行うことができto_pythonますget_db_prep_save

実際、誰かがすでにそれを行っています: hereを参照してください。

于 2009-10-06T15:14:27.473 に答える