2016-01-01 7 views
5

カスタムDjangoモデルフィールドを開発するために、私はドキュメントを読んでいます。Djangoの "deconstruct"モデルフィールド関数の目的は何ですか?

私はすでに(例とほぼ同等で、HandField:Pythonクラス上にマッピングされたフィールド...私はmodels.CharFieldなくmodels.Fieldから継承唯一の違いで)私のカスタムフィールドを開発しました。

from external_library import ExternalClass 

class ExternalClassField(models.CharField): 
    description = "An ExternalClass field" 

    def __init__(self, *args, **kwargs): 
     kwargs['max_length'] = 14 
     super(ExternalClassField, self).__init__(*args, **kwargs) 

    def from_db_value(self, value, expression, connection, context): 
     if value is None: 
      return value 
     return ExternalClass(value) 

    def to_python(self, value): 
     if isinstance(value, ExternalClass): 
      return value 

     if value is None: 
      return value 

     return ExternalClass(value) 

    def get_prep_value(self, value): 
     if value is None: 
      return value 

     if isinstance(value, ExternalClass): 
      return value.to_string() 

     return value 

フィールドは期待どおりに動作します。しかし、私はドキュメントのこの部分に固執しています:deconstruct()機能。特に

、私は理解していないことはこれです:

  • 正確に解体機能の目的は何ですか?
  • 私のフィールドは、たとえそれがなくても完璧にうまくいくのです(そして、init引数を変更しても)?
  • Djangoはどのようにdeconstruct関数を呼び出していますか?

私はわからないコードを盲目的にコピーして貼り付けたいとは思わないが、ドキュメントは明確ではない。

+0

フィールドをシリアル化するために移行で使用されます。 – knbk

答えて

12

deconstruct()メソッドは、システムによって自動的に処理できないモデルの移行を実行するのに役立ちます。解体物が呼び出されるシナリオを歩みましょう。

モデルがあり、カスタムフィールドを追加したとします。 python manage.py makemigrationsで移行しようとしています。それは、Djangoのプロジェクトに提出されていますa related ticketが既に存在だということが判明し

ValueError: Cannot serialize: Foo 
There are some values Django cannot serialize into migration files. 

、それをチェックしよう:

は、我々は次のようなエラーが発生しました。コア開発者の

ticket-issue

一つの私たちのフィールドは、呼び出し可能が含まれているため、これは動作を意図していると回答しました。

ticket-resolution

そこで、我々は、ドキュメントで何かを逃しました。呼び出し可能な値が格納されています。何らかの理由で自動的に移行することはできません。私たちは何ができる?

まあ、ValueErrorについての私達に伝えることに加えて、manage.pyも私たちのドキュメントへの便利なリンクを与えた:そのページで一度

docs-link

、我々がされるまで、少しスクロールダウンをセクション約serializing values。まあ

Django can serialize the following:

  • ...
  • Anything with a custom deconstruct() method (see below)
  • ...

、のsee belowてみましょう:ドキュメントで述べたように解体()メソッドは、__eq__()と手をつないで動作することを

You can let Django serialize your own custom class instances by giving the class a deconstruct() method. It takes no arguments, and should return a tuple of three things (path, args, kwargs):

  • path should be the Python path to the class, with the class name included as the last part (for example, myapp.custom_things.MyClass). If your class is not available at the top level of a module it is not serializable.
  • args should be a list of positional arguments to pass to your class’ init method. Everything in this list should itself be serializable.
  • kwargs should be a dict of keyword arguments to pass to your class’ init method. Every value should itself be serializable.

注:

To prevent a new migration from being created each time makemigrations is run, you should also add a __eq__() method to the decorated class. This function will be called by Django’s migration framework to detect changes between states.

私の場合は、間違いは、呼び出されてはならない値の後ろにかっこを追加することでしたが、多くの場合、移行のためのdeconstructメソッドを実装したいと思うでしょう。 (別の例ではuseful linkがあります)

+0

私は、このような答えがたくさんあることを願っています! – Nevertheless

+1

何らかの理由で、私は答えを受け入れませんでした。本当に申し訳ありません。答えは受け入れました。本当に洞察力と便利、ありがとう! – Saturnix

関連する問題