{"title":"カスタムのモデルフィールドを作成する","version":"5.0","locale":"ja","docname":"howto/custom-model-fields","url":"/ja/5.0/howto/custom-model-fields/","canonical":"https://djangodocs.dev/ja/5.0/howto/custom-model-fields/","summary":"モデルリファレンスドキュメントでは、Djangoの標準フィールドクラスである、 CharField や、 DateField などの使い方を説明しています。","html":"<h1>カスタムのモデルフィールドを作成する<a class=\"heading-anchor\" href=\"#how-to-create-custom-model-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<section id=\"introduction\">\n<h2>はじめに<a class=\"heading-anchor\" href=\"#introduction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/ja/5.0/topics/db/models/\"><span class=\"doc\">モデルリファレンス</span></a> ドキュメントでは、Djangoの標準フィールドクラスである、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> や、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\">DateField</code></a> などの使い方を説明しています。多くの場合、これらのクラスがあれば十分です。ただし、Djangoのバージョンが正確な要件を満たしていない場合や、Djangoに同梱されているものとはまったく異なるフィールドを使用したい場合があります。</p>\n<p>Django の組み込みフィールド型は、データベースで利用可能な全てのカラム型をカバーしているわけではなく、 <code class=\"docutils literal notranslate\">VARCHAR</code> や <code class=\"docutils literal notranslate\">INTEGER</code> のような一般的な型のみに対応しています。地理的な多角形や <a class=\"reference external\" href=\"https://www.postgresql.org/docs/current/sql-createtype.html\">PostgreSQL カスタム型</a> のようなユーザが作成した型など、より曖昧なカラム型については、独自の Django <code class=\"docutils literal notranslate\">Field</code> サブクラスを定義することができます。</p>\n<p>あるいは、複雑な Python オブジェクトを、標準的なデータベースのカラム型に合うようにシリアライズすることもできます。これもまた、<code class=\"docutils literal notranslate\">Field</code> サブクラスがオブジェクトをモデルで使用するのに役立つケースです。</p>\n<section id=\"our-example-object\">\n<h3>私たちのサンプルオブジェクト<a class=\"heading-anchor\" href=\"#our-example-object\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>カスタムフィールドを作成するには、細部に少し注意する必要があります。わかりやすくなるように、このドキュメントでは「ブリッジ <a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Contract_bridge\">Bridge</a> の手札のやり取りを表すPythonオブジェクトの実装」を一貫した例として説明することにします。なお、この実装例を理解するために、ブリッジのプレイルールを理解する必要はありません。52枚のカードが、伝統的に <em>北</em> 、 <em>東</em> 、 <em>南</em> および <em>西</em> と呼ばれる4人のプレイヤーに均等に配られることだけを覚えておいてください。クラスは以下のように実装します:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Hand</span><span class=\"p\">:</span>\n    <span class=\"sd\">&quot;&quot;&quot;A hand of cards (bridge style)&quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> north<span class=\"p\">,</span> east<span class=\"p\">,</span> south<span class=\"p\">,</span> west<span class=\"p\">):</span>\n        <span class=\"c1\"># Input parameters are lists of cards (&#39;Ah&#39;, &#39;9s&#39;, etc.)</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>north <span class=\"o\">=</span> north\n        <span class=\"bp\">self</span><span class=\"o\">.</span>east <span class=\"o\">=</span> east\n        <span class=\"bp\">self</span><span class=\"o\">.</span>south <span class=\"o\">=</span> south\n        <span class=\"bp\">self</span><span class=\"o\">.</span>west <span class=\"o\">=</span> west\n\n    <span class=\"c1\"># ... (other possibly useful methods omitted) ...</span>\n</code></pre></div>\n<p>これはDjangoの仕様を使っていない、普通のPythonクラスです。モデルでこれと同じようなことを実行できるようにしたいと思います（モデルの中の <code class=\"docutils literal notranslate\">hand</code> 属性は <code class=\"docutils literal notranslate\">Hand</code> インスタンスだと想定しています）</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>example <span class=\"o\">=</span> MyModel<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span>example<span class=\"o\">.</span>hand<span class=\"o\">.</span>north<span class=\"p\">)</span>\n\nnew_hand <span class=\"o\">=</span> Hand<span class=\"p\">(</span>north<span class=\"p\">,</span> east<span class=\"p\">,</span> south<span class=\"p\">,</span> west<span class=\"p\">)</span>\nexample<span class=\"o\">.</span>hand <span class=\"o\">=</span> new_hand\nexample<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>他のPythonクラスと同様に、モデルの <code class=\"docutils literal notranslate\">hand</code> 属性に割り当てたり、そこから取得したりします。コツは、そのようなオブジェクトの保存と読み込みの処理方法をDjangoに伝えることです。</p>\n<p>モデルで <code class=\"docutils literal notranslate\">Hand</code> クラスを使用するために、<strong>このクラスを変更する必要はありません</strong>。 これは、ソースコードを変更できない既存のクラスのモデルサポートを簡単に記述できるため、理想的です。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>例えば文字列や浮動小数点数のような、Pythonの標準的な型としてカスタムデータベースのカラム型を扱い、データを利用したいこともあります。このケースは <code class=\"docutils literal notranslate\">Hand</code> の例と似ているので、違いを後で説明することにします。</p>\n</aside>\n</section>\n</section>\n<section id=\"background-theory\">\n<h2>背景理論<a class=\"heading-anchor\" href=\"#background-theory\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"database-storage\">\n<h3>データベースストレージ<a class=\"heading-anchor\" href=\"#database-storage\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>モデルフィールドから始めましょう。分解すると、モデルフィールドは通常のPythonオブジェクト（文字列、ブール値、 <code class=\"docutils literal notranslate\">datetime</code> 、あるいは <code class=\"docutils literal notranslate\">Hand</code> のような複雑なもの）を、データベースを扱うときに便利な形式に変換する方法を提供します。(このような形式はシリアライズの際にも便利ですが、後で説明するように、データベース側を制御できるようになれば、その方が簡単です)。</p>\n<p>モデルのフィールドは、既存のデータベースのカラムの型に適合するように何らかの方法で変換されなければなりません。データベースによって有効なカラム型のセットは異なりますが、利用できる型が決まっているという決まりは同じです。データベースに保存したいものはすべて、これらの型のいずれかに適合しなければなりません。</p>\n<p>通常、特定のデータベースの列タイプに一致するようにDjangoフィールドを作成するか、データを文字列などに変換する方法が必要になります。</p>\n<p><code class=\"docutils literal notranslate\">Hand</code> の例では、すべてのカードをあらかじめ決められた順序で連結することで、カードデータを104文字の文字列に変換できます。たとえば、すべての <em>北</em> カード、次に <em>東</em> 、 <em>南</em> および <em>西</em> カードです。 したがって、<code class=\"docutils literal notranslate\">Hand</code> オブジェクトをデータベースのテキストまたは文字列に保存できます。</p>\n</section>\n<section id=\"what-does-a-field-class-do\">\n<h3>フィールドクラスが行うこと<a class=\"heading-anchor\" href=\"#what-does-a-field-class-do\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Djangoのすべてのフィールド（およびこのドキュメントで <em>フィールド (Field)</em> と言うときは、常に <a class=\"reference internal\" href=\"/ja/5.0/ref/forms/fields/\"><span class=\"doc\">フォームフィールド</span></a> ではなくモデルフィールドを意味します）は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.Field</code></a> のサブクラスです。 Django がフィールドについて記録する情報のほとんどは、名前、ヘルプテキスト、一意性など、すべてのフィールドに共通です。すべての情報の保存は <code class=\"docutils literal notranslate\">Field</code> によって処理されます。<code class=\"docutils literal notranslate\">Field</code> ができることの詳細については、後で詳しく説明します。とりあえず、すべてが <code class=\"docutils literal notranslate\">Field</code> から派生し、クラスの動作の重要な部分をカスタマイズすると言うだけで十分です。</p>\n<p>Djangoフィールドクラスは、モデル属性に格納されているものではないことを理解することが重要です。 モデル属性には通常のPythonオブジェクトが含まれます。 モデルで定義するフィールドクラスは、モデルクラスが作成されるときに実際に <code class=\"docutils literal notranslate\">Meta</code> クラスに保存されます（これを行う方法の正確な詳細はここでは重要ではありません）。 これは、属性を作成および変更するだけの場合、フィールドクラスは必要ないためです。 代わりに、属性値とデータベースに保存されているもの、または <a class=\"reference internal\" href=\"/ja/5.0/topics/serialization/\"><span class=\"doc\">シリアライザ</span></a> に送信されるものとの間で変換するための機構を提供します。</p>\n<p>独自のカスタムフィールドを作成する場合は、このことに留意してください。 作成するDjangoの <code class=\"docutils literal notranslate\">Field</code> サブクラスは、Pythonインスタンスとデータベース/シリアライザーの値をさまざまな方法で変換するための機構を提供します（たとえば、値の保存とルックアップでの値の使用には違いがあります）。 これが少しトリッキーに聞こえる場合でも、心配しないでください。以下の例で明らかになります。 カスタムフィールドが必要な場合、しばしば2つのクラスを作成することになります:</p>\n<ul class=\"simple\">\n<li><p>最初のクラスは、ユーザーが操作するPythonオブジェクトです。彼らはそれをモデル属性に割り当て、そのようなものを表示するためにそれから読み込みます。これは、この例の <code class=\"docutils literal notranslate\">Hand</code> クラスです。</p></li>\n<li><p>2番目のクラスは <code class=\"docutils literal notranslate\">Field</code> サブクラスです。これは、最初のクラスを永続ストレージ形式とPython形式の間で変換する方法を知っているクラスです。</p></li>\n</ul>\n</section>\n</section>\n<section id=\"writing-a-field-subclass\">\n<h2>フィールドサブクラスを書く<a class=\"heading-anchor\" href=\"#writing-a-field-subclass\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> のサブクラス化を考える前に、まず、新しいフィールドが、既存のどの <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> クラスに最も似ているかを考えてください。既存の Django フィールドをサブクラス化して、手間を省くことはできませんか？そうでなければ、すべてのフィールドの基底となる、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> クラスをサブクラス化すべきです。</p>\n<p>新しいフィールドの初期化は、ケース固有の引数を共通の引数から分離し、後者を <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> の <code class=\"docutils literal notranslate\">__init__()</code> メソッドに渡すことです。 （または親クラスに対して）。</p>\n<p>この例では、フィールドを <code class=\"docutils literal notranslate\">HandField</code> と呼ぶことにします。（ <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> サブクラス <code class=\"docutils literal notranslate\">&lt;Something&gt;Field</code> と名付けることをオススメします。 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> サブクラスであることが簡単にわかるためです）\n既存のフィールドのようには動作しないため、この例では <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> から直接サブクラス化しています。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    description <span class=\"o\">=</span> <span class=\"s2\">&quot;A hand of cards (bridge style)&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        kwargs<span class=\"p\">[</span><span class=\"s2\">&quot;max_length&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">104</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n</code></pre></div>\n<p>私たちの <code class=\"docutils literal notranslate\">HandField</code> は、ほとんどの標準フィールドオプションを受け入れます（以下のリストを参照してください）。しかし、52枚のカードの値とそれらのスート（マーク）を保持するだけで十分なため、固定長を持つようにします。合計で104文字です。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>多くのDjangoのモデルフィールドは、受け取ってもなにも起こらないオプションを受け取ります。例えば、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.editable\" title=\"django.db.models.Field.editable\"><code class=\"xref py py-attr docutils literal notranslate\">editable</code></a> と <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField.auto_now\" title=\"django.db.models.DateField.auto_now\"><code class=\"xref py py-attr docutils literal notranslate\">auto_now</code></a> は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField\" title=\"django.db.models.DateField\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.DateField</code></a> に渡すことができますが、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.editable\" title=\"django.db.models.Field.editable\"><code class=\"xref py py-attr docutils literal notranslate\">editable</code></a> のパラメーターを無視します。（ <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField.auto_now\" title=\"django.db.models.DateField.auto_now\"><code class=\"xref py py-attr docutils literal notranslate\">auto_now</code></a> には <code class=\"docutils literal notranslate\">editable=False</code> がセットされています）この場合、エラーは発生しません。</p>\n<p>この振る舞いはフィールドクラスをシンプルにします。なぜなら、必要のないオプションをチェックする必要がないからです。すべてのオプションを親クラスに渡し、オプションを使用しないのです。フィールドにより厳密にオプションを扱ってほしいのか、より柔軟なカレントフィールドの動作を使うのかは、使う人次第です。</p>\n</aside>\n<p><code class=\"docutils literal notranslate\">Field.__init__()</code> メソッドは以下のパラメーターを取ります:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.verbose_name\" title=\"django.db.models.Field.verbose_name\"><code class=\"xref py py-attr docutils literal notranslate\">verbose_name</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">name</code></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\">primary_key</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.CharField.max_length\" title=\"django.db.models.CharField.max_length\"><code class=\"xref py py-attr docutils literal notranslate\">max_length</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.unique\" title=\"django.db.models.Field.unique\"><code class=\"xref py py-attr docutils literal notranslate\">unique</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\">blank</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.null\" title=\"django.db.models.Field.null\"><code class=\"xref py py-attr docutils literal notranslate\">null</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_index\" title=\"django.db.models.Field.db_index\"><code class=\"xref py py-attr docutils literal notranslate\">db_index</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">rel</code>: 関連フィールドに使用される (<a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> など)。上級者向けです。</p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.default\" title=\"django.db.models.Field.default\"><code class=\"xref py py-attr docutils literal notranslate\">default</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.editable\" title=\"django.db.models.Field.editable\"><code class=\"xref py py-attr docutils literal notranslate\">editable</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">serialize</code>: <code class=\"docutils literal notranslate\">False</code> の場合、Django の <a class=\"reference internal\" href=\"/ja/5.0/topics/serialization/\"><span class=\"doc\">シリアライザ</span></a> にモデルが渡されたときに、フィールドをシリアライズしません。デフォルトの値は <code class=\"docutils literal notranslate\">True</code> です。</p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.unique_for_date\" title=\"django.db.models.Field.unique_for_date\"><code class=\"xref py py-attr docutils literal notranslate\">unique_for_date</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.unique_for_month\" title=\"django.db.models.Field.unique_for_month\"><code class=\"xref py py-attr docutils literal notranslate\">unique_for_month</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.unique_for_year\" title=\"django.db.models.Field.unique_for_year\"><code class=\"xref py py-attr docutils literal notranslate\">unique_for_year</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.choices\" title=\"django.db.models.Field.choices\"><code class=\"xref py py-attr docutils literal notranslate\">choices</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.help_text\" title=\"django.db.models.Field.help_text\"><code class=\"xref py py-attr docutils literal notranslate\">help_text</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_column\" title=\"django.db.models.Field.db_column\"><code class=\"xref py py-attr docutils literal notranslate\">db_column</code></a></p></li>\n<li><p>もしバックエンドが <a class=\"reference internal\" href=\"/ja/5.0/topics/db/tablespaces/\"><span class=\"doc\">テーブル空間 (tablespace)</span></a> をサポートする場合、<a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_tablespace\" title=\"django.db.models.Field.db_tablespace\"><code class=\"xref py py-attr docutils literal notranslate\">db_tablespace</code></a>: はインデックスの作成のみ行います。通常、このオプションは無視できます。</p></li>\n<li><p>モデル継承で使用される <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\">OneToOneField</code></a> のように、フィールドが自動的に作成された場合は、<a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.auto_created\" title=\"django.db.models.Field.auto_created\"><code class=\"xref py py-attr docutils literal notranslate\">auto_created</code></a> は <code class=\"docutils literal notranslate\">True</code> です。 高度な使用向けです。</p></li>\n</ul>\n<p>上記のリストに説明のないオプションはすべて、通常のDjangoフィールドと同じ意味を持ちます。例と詳細については、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/\"><span class=\"doc\">フィールドのドキュメント</span></a> を参照してください。</p>\n<section id=\"field-deconstruction\">\n<span id=\"custom-field-deconstruct-method\"></span><h3>フィールドの解体<a class=\"heading-anchor\" href=\"#field-deconstruction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">__init__()</code> メソッドとは対照的なものとして、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.deconstruct\" title=\"django.db.models.Field.deconstruct\"><code class=\"xref py py-meth docutils literal notranslate\">deconstruct()</code></a> メソッドがあります。これは <a class=\"reference internal\" href=\"/ja/5.0/topics/migrations/\"><span class=\"doc\">モデルのマイグレーション</span></a> 中に使用されるもので、新しいフィールドのインスタンスを取得する方法、インスタンスをどのようにシリアライズして減らすかの方法をDjangoに指示します。特に、インスタンスを再生成するためにどの引数を <code class=\"docutils literal notranslate\">__init__()</code> に渡すかを指示します。</p>\n<p>継承元のフィールドの上に追加のオプションを追加していない場合、新しい <code class=\"docutils literal notranslate\">deconstruct()</code> メソッドを記述する必要はありません。 ただし、<code class=\"docutils literal notranslate\">__init__()</code> で渡される引数を変更する場合（<code class=\"docutils literal notranslate\">HandField</code> のように）、渡される値を補足する必要があります。</p>\n<p><code class=\"docutils literal notranslate\">deconstruct()</code> 関数は4要素のタプルを返します。それは、フィールドの属性、インポートするフィールドクラスのフルパス、位置引数（リスト型）、キーワード引数（辞書型）です。この関数は <code class=\"docutils literal notranslate\">deconstruct()</code> メソッドとは異なることに注意してください。 <code class=\"docutils literal notranslate\">deconstruct()</code> メソッドは <a class=\"reference internal\" href=\"/ja/5.0/topics/migrations/#custom-deconstruct-method\"><span class=\"std std-ref\">カスタムクラスのためのもの</span></a> で、3要素のタプルを返します。</p>\n<p>カスタムフィールドの作成者は、最初の2つの値を気にする必要はありません。 ベース <code class=\"docutils literal notranslate\">Field</code> クラスには、フィールドの属性名とインポートパスを計算するためのすべてのコードがあります。 ただし、位置引数とキーワード引数は、変更する可能性が高いため、注意する必要があります。</p>\n<p>たとえば、 <code class=\"docutils literal notranslate\">HandField</code> クラスでは、常に <code class=\"docutils literal notranslate\">__init__()</code> でmax_lengthを強制的に設定しています。 <code class=\"docutils literal notranslate\">Field</code> ベースクラスの <code class=\"docutils literal notranslate\">deconstruct()</code> メソッドはこれを見て、キーワード引数でそれを返そうとします。 したがって、読みやすくするためにキーワード引数から削除できます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        kwargs<span class=\"p\">[</span><span class=\"s2\">&quot;max_length&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">104</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">deconstruct</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        name<span class=\"p\">,</span> path<span class=\"p\">,</span> args<span class=\"p\">,</span> kwargs <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>deconstruct<span class=\"p\">()</span>\n        <span class=\"k\">del</span> kwargs<span class=\"p\">[</span><span class=\"s2\">&quot;max_length&quot;</span><span class=\"p\">]</span>\n        <span class=\"k\">return</span> name<span class=\"p\">,</span> path<span class=\"p\">,</span> args<span class=\"p\">,</span> kwargs\n</code></pre></div>\n<p>新しいキーワード引数を追加する場合、自分で <code class=\"docutils literal notranslate\">kwargs</code> に値を設定する <code class=\"docutils literal notranslate\">deconstruct()</code> でコードを記述する必要があります。 また、デフォルト値が使用されている場合など、フィールドの状態を再構築する必要がない場合は、<code class=\"docutils literal notranslate\">kwargs</code> から値を省略してください:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">CommaSepField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"s2\">&quot;Implements comma-separated storage of lists&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> separator<span class=\"o\">=</span><span class=\"s2\">&quot;,&quot;</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>separator <span class=\"o\">=</span> separator\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">deconstruct</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        name<span class=\"p\">,</span> path<span class=\"p\">,</span> args<span class=\"p\">,</span> kwargs <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>deconstruct<span class=\"p\">()</span>\n        <span class=\"c1\"># Only include kwarg if it&#39;s not the default</span>\n        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span>separator <span class=\"o\">!=</span> <span class=\"s2\">&quot;,&quot;</span><span class=\"p\">:</span>\n            kwargs<span class=\"p\">[</span><span class=\"s2\">&quot;separator&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>separator\n        <span class=\"k\">return</span> name<span class=\"p\">,</span> path<span class=\"p\">,</span> args<span class=\"p\">,</span> kwargs\n</code></pre></div>\n<p>より複雑な例はこのドキュメントの範囲外ですが、これだけは覚えておいてください - <code class=\"docutils literal notranslate\">deconstruct()</code> は、フィールドインスタンスのどのような設定に対しても、その状態を再構築するために <code class=\"docutils literal notranslate\">__init__</code> に渡す引数を返さなければなりません。</p>\n<p><code class=\"docutils literal notranslate\">Field</code> スーパークラス内の引数に新しいデフォルト値を設定する場合には、特に注意してください。古いデフォルト値を使うと消えるようにするのではなく、デフォルト値が常に含まれるようにしてください。</p>\n<p>また、値を位置引数として返さないようにしてください。 可能な限り、将来の互換性を最大限にするために、キーワード引数として値を返してください。コンストラクタの引数リストにおける位置よりも、頻繁に引数の名前を変更する場合、位置引数で指定しがちになるかもしれません。しかし、利用者はかなり長期間（おそらく何年も）にわたって、シリアライズされたバージョンからフィールドを再構築することに注意してください。これはバージョンのライフサイクルの長さにも依存します。</p>\n<p>フィールドを含む移行を調べることで分解の結果を確認できます。フィールドを分解して再構築することで、単体テストで分解をテストできます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>name<span class=\"p\">,</span> path<span class=\"p\">,</span> args<span class=\"p\">,</span> kwargs <span class=\"o\">=</span> my_field_instance<span class=\"o\">.</span>deconstruct<span class=\"p\">()</span>\nnew_instance <span class=\"o\">=</span> MyField<span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n<span class=\"bp\">self</span><span class=\"o\">.</span>assertEqual<span class=\"p\">(</span>my_field_instance<span class=\"o\">.</span>some_attribute<span class=\"p\">,</span> new_instance<span class=\"o\">.</span>some_attribute<span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"field-attributes-not-affecting-database-column-definition\">\n<span id=\"custom-field-non-db-attrs\"></span><h3>データベースのカラム定義に影響しないフィールド属性<a class=\"heading-anchor\" href=\"#field-attributes-not-affecting-database-column-definition\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">Field.non_db_attrs</code> をオーバーライドすることで、カラム定義に影響しないフィールドの属性をカスタマイズできます。これはモデルのマイグレーションの間に使われ、no-opの <code class=\"docutils literal notranslate\">AlterField</code> 操作を検出します。</p>\n<p>例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CommaSepField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span> <span class=\"nf\">non_db_attrs</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>non_db_attrs <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"s2\">&quot;separator&quot;</span><span class=\"p\">,)</span>\n</code></pre></div>\n</section>\n<section id=\"changing-a-custom-field-s-base-class\">\n<h3>カスタムフィールドのベースクラスを変更する<a class=\"heading-anchor\" href=\"#changing-a-custom-field-s-base-class\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>カスタムフィールドの基底クラスを変更することはできません。なぜなら、 Django はその変更を検知できず、マイグレーションも行わないからです。例えば次のように書き始めたとして、:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CustomCharField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>CharField<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>そして、代わりに <code class=\"docutils literal notranslate\">TextField</code> を使用することに決めた場合、サブクラスを次のように変更することはできません:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CustomCharField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>TextField<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>代わりに、新しいカスタムフィールドクラスを作成し、モデルを更新してそれを参照する必要があります:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CustomCharField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>CharField<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">CustomTextField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>TextField<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/ja/5.0/topics/migrations/#migrations-removing-model-fields\"><span class=\"std std-ref\">フィールドを削除する</span></a> で説明したように、それを参照するマイグレーションがある限り、元の <code class=\"docutils literal notranslate\">CustomCharField</code> クラスを保持する必要があります。</p>\n</section>\n<section id=\"documenting-your-custom-field\">\n<h3>カスタムフィールドのドキュメントを書く<a class=\"heading-anchor\" href=\"#documenting-your-custom-field\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>いつものように、フィールドタイプのドキュメントを作成し、それがどんなものかをユーザがわかるようにしましょう。開発者にとって便利な docstring を提供するだけでなく、 <a class=\"reference internal\" href=\"/ja/5.0/ref/contrib/admin/admindocs/\"><span class=\"doc\">django.contrib.admindocs</span></a> アプリケーションを通して、管理者アプリのユーザにフィールドタイプの短い説明を表示することもできます。これを行うには、カスタムフィールドの <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.description\" title=\"django.db.models.Field.description\"><code class=\"xref py py-attr docutils literal notranslate\">description</code></a> クラス属性に説明文を記述します。上記の例では、 <code class=\"docutils literal notranslate\">admindocs</code> アプリケーションが表示する <code class=\"docutils literal notranslate\">HandField</code> の説明は 'A hand of cards (bridge style)' （日本語で「手札(ブリッジスタイル)」の意）となります。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.0/ref/contrib/admin/admindocs/#module-django.contrib.admindocs\" title=\"django.contrib.admindocs: Django's admin documentation generator.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.admindocs</code></a> の表示では、フィールドの説明は <code class=\"docutils literal notranslate\">field.__dict__</code> によって補完され、説明文にフィールドの引数を組み込むことができます。例えば、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> の説明は次のようになります:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>description <span class=\"o\">=</span> _<span class=\"p\">(</span><span class=\"s2\">&quot;String (up to </span><span class=\"si\">%(max_length)s</span><span class=\"s2\">)&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"useful-methods\">\n<h3>便利なメソッド<a class=\"heading-anchor\" href=\"#useful-methods\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> サブクラスを作成したら、フィールドの動作に応じて、いくつかの標準メソッドをオーバーライドすることを検討できます。以下のメソッドのリストは、おおよそ重要度の高いものから順に並んでいるので、上から始めてください。</p>\n<section id=\"custom-database-types\">\n<span id=\"id1\"></span><h4>カスタムデータベースタイプ<a class=\"heading-anchor\" href=\"#custom-database-types\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\">mytype</code> というPostgreSQLのカスタム型を作成したとします。このとき、 <code class=\"docutils literal notranslate\">Field</code> をサブクラス化し、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> 関数を以下のように実装できます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MytypeField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;mytype&quot;</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">MytypeField</code> を取得したら、他の <code class=\"docutils literal notranslate\">Field</code> タイプと同様に、どのモデルでも使用できます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">Person</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">80</span><span class=\"p\">)</span>\n    something_else <span class=\"o\">=</span> MytypeField<span class=\"p\">()</span>\n</code></pre></div>\n<p>データベースに依存しないアプリケーションを構築することを目指している場合、データベースカラムの型の違いを考慮する必要があります。たとえば、PostgreSQL の日付や時刻のカラムの型は <code class=\"docutils literal notranslate\">timestamp</code> と呼ばれますが、同じカラムが MySQL では <code class=\"docutils literal notranslate\">datetime</code> と呼ばれます。この違いは <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> メソッド内で <code class=\"docutils literal notranslate\">connection.vendor</code> 属性をチェックすることでハンドリングできます。現在のビルトインされているベンダー名は、<code class=\"docutils literal notranslate\">sqlite</code>、<code class=\"docutils literal notranslate\">postgresql</code>、<code class=\"docutils literal notranslate\">mysql</code>、<code class=\"docutils literal notranslate\">oracle</code> です。</p>\n<p>例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">MyDateField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">if</span> connection<span class=\"o\">.</span>vendor <span class=\"o\">==</span> <span class=\"s2\">&quot;mysql&quot;</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;datetime&quot;</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"s2\">&quot;timestamp&quot;</span>\n</code></pre></div>\n<p>Django は、アプリケーションのために <code class=\"docutils literal notranslate\">CREATE TABLE</code> ステートメントを構築するとき、つまり最初にテーブルを作成するときに <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> と <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.rel_db_type\" title=\"django.db.models.Field.rel_db_type\"><code class=\"xref py py-meth docutils literal notranslate\">rel_db_type()</code></a> メソッドを呼びます。このメソッドは、モデルのフィールドを含む <code class=\"docutils literal notranslate\">WHERE</code> 句を構築するとき、つまり QuerySet の <code class=\"docutils literal notranslate\">get()</code>、<code class=\"docutils literal notranslate\">filter()</code>、<code class=\"docutils literal notranslate\">exclude()</code> などのメソッドを使用してデータを取得するときにも呼ばれます。</p>\n<p>一部のデータベースカラムの型は <code class=\"docutils literal notranslate\">CHAR(25)</code> などのパラメータを受け付けます。ここで、パラメータ <code class=\"docutils literal notranslate\">25</code> はカラムの最大長を表します。このような場合、パラメータを <code class=\"docutils literal notranslate\">db_type()</code> メソッド内でハードコードするよりも、モデル内で指定したほうがより柔軟になります。たとえば、ここで示すように、<code class=\"docutils literal notranslate\">CharMaxlength25Field</code> のようなフィールドを持つ意味はあまりありません。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># This is a silly example of hard-coded parameters.</span>\n<span class=\"k\">class</span> <span class=\"nc\">CharMaxlength25Field</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;char(25)&quot;</span>\n\n\n<span class=\"c1\"># In the model:</span>\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    my_field <span class=\"o\">=</span> CharMaxlength25Field<span class=\"p\">()</span>\n</code></pre></div>\n<p>これを行うためのよりよい方法は、実行時に、つまりクラスがインスタンス化されるときにパラメータを指定できるようにする方法です。そのためには、次のように <code class=\"docutils literal notranslate\">Field.__init__()</code> を実装します。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># This is a much more flexible example.</span>\n<span class=\"k\">class</span> <span class=\"nc\">BetterCharField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> max_length<span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span>max_length <span class=\"o\">=</span> max_length\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;char(</span><span class=\"si\">%s</span><span class=\"s2\">)&quot;</span> <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span>max_length\n\n\n<span class=\"c1\"># In the model:</span>\n<span class=\"k\">class</span> <span class=\"nc\">MyModel</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    my_field <span class=\"o\">=</span> BetterCharField<span class=\"p\">(</span><span class=\"mi\">25</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>最後に、カラムが本当に複雑な SQL のセットアップを必要とする場合、<a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> から <code class=\"docutils literal notranslate\">None</code> を返してください。こうすると、Django の SQL 生成コードがこのフィールドをスキップするようになります。その後、別の方法で正しいテーブルにカラムを作成すする必要がありますが、Django に邪魔をしないように伝えることができます。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.rel_db_type\" title=\"django.db.models.Field.rel_db_type\"><code class=\"xref py py-meth docutils literal notranslate\">rel_db_type()</code></a> メソッドは、他のフィールドを指す <code class=\"docutils literal notranslate\">ForeignKey</code> や <code class=\"docutils literal notranslate\">OneToOneField</code> などのフィールドによって、データベースのカラムのデータ型を特定するために呼ばれます。たとえば、<code class=\"docutils literal notranslate\">UnsignedAutoField</code> がある場合、同じデータ型を使うためにそのフィールドを指す外部キーも必要になります。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># MySQL unsigned integer (range 0 to 4294967295).</span>\n<span class=\"k\">class</span> <span class=\"nc\">UnsignedAutoField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>AutoField<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;integer UNSIGNED AUTO_INCREMENT&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">rel_db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;integer UNSIGNED&quot;</span>\n</code></pre></div>\n</section>\n<section id=\"converting-values-to-python-objects\">\n<span id=\"id2\"></span><h4>変数を Python オブジェクトに変換する<a class=\"heading-anchor\" href=\"#converting-values-to-python-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>もしカスタムの <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> クラスが文字列、日付、整数、または浮動小数点数よりも複雑なデータ構造を扱う場合は、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.from_db_value\" title=\"django.db.models.Field.from_db_value\"><code class=\"xref py py-meth docutils literal notranslate\">from_db_value()</code></a> と <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.to_python\" title=\"django.db.models.Field.to_python\"><code class=\"xref py py-meth docutils literal notranslate\">to_python()</code></a> をオーバーライドする必要があるかもしれません。</p>\n<p>フィールドのサブクラスに存在する場合、データがデータベースから読み込まれるすべての状況で、 <code class=\"docutils literal notranslate\">from_db_value()</code> が呼び出されます。これには集計や <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\">values()</code></a> の呼び出しも含まれます。</p>\n<p><code class=\"docutils literal notranslate\">to_python()</code> は、デシリアライズ時やフォームから使用される <a class=\"reference internal\" href=\"/ja/5.0/ref/models/instances/#django.db.models.Model.clean\" title=\"django.db.models.Model.clean\"><code class=\"xref py py-meth docutils literal notranslate\">clean()</code></a> メソッドの中で呼び出されます。</p>\n<p>一般的なルールとして、 <code class=\"docutils literal notranslate\">to_python()</code> は以下の引数を適切に処理するべきです。</p>\n<ul class=\"simple\">\n<li><p>正しいタイプのインスタンス（例：このページの例でいう <code class=\"docutils literal notranslate\">Hand</code> ）。</p></li>\n<li><p>文字列</p></li>\n<li><p><code class=\"docutils literal notranslate\">None</code> (フィールドが <code class=\"docutils literal notranslate\">null=True</code> を許す場合)</p></li>\n</ul>\n<p>私たちの <code class=\"docutils literal notranslate\">HandField</code> クラスでは、データをデータベースの <code class=\"docutils literal notranslate\">VARCHAR</code> フィールドとして保存しているため、 <code class=\"docutils literal notranslate\">from_db_value()</code> で文字列と <code class=\"docutils literal notranslate\">None</code> を処理できる必要があります。 <code class=\"docutils literal notranslate\">to_python()</code> では、 <code class=\"docutils literal notranslate\">Hand</code> のインスタンスも処理する必要があります。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">re</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.core.exceptions</span> <span class=\"kn\">import</span> ValidationError\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.utils.translation</span> <span class=\"kn\">import</span> gettext_lazy <span class=\"k\">as</span> _\n\n\n<span class=\"k\">def</span> <span class=\"nf\">parse_hand</span><span class=\"p\">(</span>hand_string<span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;Takes a string of cards and splits into a full hand.&quot;&quot;&quot;</span>\n    p1 <span class=\"o\">=</span> re<span class=\"o\">.</span>compile<span class=\"p\">(</span><span class=\"s2\">&quot;.</span><span class=\"si\">{26}</span><span class=\"s2\">&quot;</span><span class=\"p\">)</span>\n    p2 <span class=\"o\">=</span> re<span class=\"o\">.</span>compile<span class=\"p\">(</span><span class=\"s2\">&quot;..&quot;</span><span class=\"p\">)</span>\n    args <span class=\"o\">=</span> <span class=\"p\">[</span>p2<span class=\"o\">.</span>findall<span class=\"p\">(</span>x<span class=\"p\">)</span> <span class=\"k\">for</span> x <span class=\"ow\">in</span> p1<span class=\"o\">.</span>findall<span class=\"p\">(</span>hand_string<span class=\"p\">)]</span>\n    <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span>args<span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"mi\">4</span><span class=\"p\">:</span>\n        <span class=\"k\">raise</span> ValidationError<span class=\"p\">(</span>_<span class=\"p\">(</span><span class=\"s2\">&quot;Invalid input for a Hand instance&quot;</span><span class=\"p\">))</span>\n    <span class=\"k\">return</span> Hand<span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">from_db_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> expression<span class=\"p\">,</span> connection<span class=\"p\">):</span>\n        <span class=\"k\">if</span> value <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> value\n        <span class=\"k\">return</span> parse_hand<span class=\"p\">(</span>value<span class=\"p\">)</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">to_python</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span>value<span class=\"p\">,</span> Hand<span class=\"p\">):</span>\n            <span class=\"k\">return</span> value\n\n        <span class=\"k\">if</span> value <span class=\"ow\">is</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> value\n\n        <span class=\"k\">return</span> parse_hand<span class=\"p\">(</span>value<span class=\"p\">)</span>\n</code></pre></div>\n<p>これらのメソッドからは常に <code class=\"docutils literal notranslate\">Hand</code> インスタンスが返されることに注意してください。これは、モデルの属性に保存したいPythonオブジェクトの型です。</p>\n<p><code class=\"docutils literal notranslate\">to_python()</code> において、値の変換中に何か問題が発生した場合は、 <a class=\"reference internal\" href=\"/ja/5.0/ref/exceptions/#django.core.exceptions.ValidationError\" title=\"django.core.exceptions.ValidationError\"><code class=\"xref py py-exc docutils literal notranslate\">ValidationError</code></a> 例外を発生させる必要があります。</p>\n</section>\n<section id=\"converting-python-objects-to-query-values\">\n<span id=\"id3\"></span><h4>Python オブジェクトをクエリ変数に変換する<a class=\"heading-anchor\" href=\"#converting-python-objects-to-query-values\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>データベースを使用するには両方の変換が必要なので、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.from_db_value\" title=\"django.db.models.Field.from_db_value\"><code class=\"xref py py-meth docutils literal notranslate\">from_db_value()</code></a> をオーバーライドする場合は、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_prep_value\" title=\"django.db.models.Field.get_prep_value\"><code class=\"xref py py-meth docutils literal notranslate\">get_prep_value()</code></a> もオーバーライドして Python オブジェクトをクエリの値に戻す必要があります。</p>\n<p>例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;&quot;</span><span class=\"o\">.</span>join<span class=\"p\">(</span>\n            <span class=\"p\">[</span><span class=\"s2\">&quot;&quot;</span><span class=\"o\">.</span>join<span class=\"p\">(</span>l<span class=\"p\">)</span> <span class=\"k\">for</span> l <span class=\"ow\">in</span> <span class=\"p\">(</span>value<span class=\"o\">.</span>north<span class=\"p\">,</span> value<span class=\"o\">.</span>east<span class=\"p\">,</span> value<span class=\"o\">.</span>south<span class=\"p\">,</span> value<span class=\"o\">.</span>west<span class=\"p\">)]</span>\n        <span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>カスタムフィールドでMySQLの <code class=\"docutils literal notranslate\">CHAR</code> 、<code class=\"docutils literal notranslate\">VARCHAR</code> 、<code class=\"docutils literal notranslate\">TEXT</code> 型を使用する場合は、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_prep_value\" title=\"django.db.models.Field.get_prep_value\"><code class=\"xref py py-meth docutils literal notranslate\">get_prep_value()</code></a> が常に文字列型を返すようにする必要があります。MySQL はこれらの型に対して整数を指定してクエリを実行したとき、柔軟で想定困難なマッチングを行うため、クエリの結果に予想外のオブジェクトが含まれてしまうことがあります。この問題は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_prep_value\" title=\"django.db.models.Field.get_prep_value\"><code class=\"xref py py-meth docutils literal notranslate\">get_prep_value()</code></a> から常に文字列型を返せば発生しません。</p>\n</aside>\n</section>\n<section id=\"converting-query-values-to-database-values\">\n<span id=\"id4\"></span><h4>クエリの変数をデータベースの変数に変換する<a class=\"heading-anchor\" href=\"#converting-query-values-to-database-values\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>いくつかのデータ型(例えば、日付)はデータベースのバックエンドで使用する前に特定の形式にする必要があります。 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_db_prep_value\" title=\"django.db.models.Field.get_db_prep_value\"><code class=\"xref py py-meth docutils literal notranslate\">get_db_prep_value()</code></a> はこれらの変換を行うメソッドです。クエリに使用される特定の接続は <code class=\"docutils literal notranslate\">connection</code> パラメータとして渡されます。これにより、必要に応じてバックエンド固有の変換ロジックを使用できます。</p>\n<p>例えば、Django は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.BinaryField\" title=\"django.db.models.BinaryField\"><code class=\"xref py py-class docutils literal notranslate\">BinaryField</code></a> で以下のメソッドを使います:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span> <span class=\"nf\">get_db_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n    value <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_db_prep_value<span class=\"p\">(</span>value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"p\">)</span>\n    <span class=\"k\">if</span> value <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"k\">return</span> connection<span class=\"o\">.</span>Database<span class=\"o\">.</span>Binary<span class=\"p\">(</span>value<span class=\"p\">)</span>\n    <span class=\"k\">return</span> value\n</code></pre></div>\n<p>カスタムフィールドを保存する際に、通常のクエリパラメータで使われる変換とは別の特別な変換が必要な場合、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_db_prep_save\" title=\"django.db.models.Field.get_db_prep_save\"><code class=\"xref py py-meth docutils literal notranslate\">get_db_prep_save()</code></a> をオーバーライドできます。</p>\n</section>\n<section id=\"preprocessing-values-before-saving\">\n<span id=\"id5\"></span><h4>保存する前に値を前処理する場合<a class=\"heading-anchor\" href=\"#preprocessing-values-before-saving\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>保存する直前に値を前処理したい場合は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.pre_save\" title=\"django.db.models.Field.pre_save\"><code class=\"xref py py-meth docutils literal notranslate\">pre_save()</code></a> を使います。例えば、 Django の <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> はこのメソッドを使って、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField.auto_now\" title=\"django.db.models.DateField.auto_now\"><code class=\"xref py py-attr docutils literal notranslate\">auto_now</code></a> や <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.DateField.auto_now_add\" title=\"django.db.models.DateField.auto_now_add\"><code class=\"xref py py-attr docutils literal notranslate\">auto_now_add</code></a> に正しく属性を設定します。</p>\n<p>もしこのメソッドをオーバーライドするならば、最後にその属性の値を返す必要があります。さらに、もしその値になんらかの変更を加えたならば、そのモデルへの参照を含んでいるコードが常に正しい値を指すように、モデルの属性を更新しなくてはなりません。</p>\n</section>\n<section id=\"specifying-the-form-field-for-a-model-field\">\n<span id=\"specifying-form-field-for-model-field\"></span><h4>モデルフィールドのフォームフィールドの指定<a class=\"heading-anchor\" href=\"#specifying-the-form-field-for-a-model-field\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><a class=\"reference internal\" href=\"/ja/5.0/topics/forms/modelforms/#django.forms.ModelForm\" title=\"django.forms.ModelForm\"><code class=\"xref py py-class docutils literal notranslate\">ModelForm</code></a> で使用するフォームフィールドをカスタマイズするには、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.formfield\" title=\"django.db.models.Field.formfield\"><code class=\"xref py py-meth docutils literal notranslate\">formfield()</code></a> をオーバーライドします。</p>\n<p>フォームフィールドのクラスは <code class=\"docutils literal notranslate\">form_class</code> と <code class=\"docutils literal notranslate\">choices_form_class</code> 引数で指定できます。これらの引数を指定しなければ、 <a class=\"reference internal\" href=\"/ja/5.0/ref/forms/fields/#django.forms.CharField\" title=\"django.forms.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> または <a class=\"reference internal\" href=\"/ja/5.0/ref/forms/fields/#django.forms.TypedChoiceField\" title=\"django.forms.TypedChoiceField\"><code class=\"xref py py-class docutils literal notranslate\">TypedChoiceField</code></a> が使用されます。</p>\n<p>すべての <code class=\"docutils literal notranslate\">kwargs</code> 辞書は、フォームフィールドの <code class=\"docutils literal notranslate\">__init__()</code> メソッドに直接渡されます。通常、 <code class=\"docutils literal notranslate\">form_class</code> ( または <code class=\"docutils literal notranslate\">choices_form_class</code> ) 引数に適切なデフォルト値を設定し、それ以降の処理を親クラスに委譲するだけです。そのためには、カスタムフォームフィールド (そしてフォームウィジェット) を書く必要があるかもしれません。これについては <a class=\"reference internal\" href=\"/ja/5.0/topics/forms/\"><span class=\"doc\">フォームのドキュメント</span></a> を参照してください。</p>\n<p>上の例に続き、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.formfield\" title=\"django.db.models.Field.formfield\"><code class=\"xref py py-meth docutils literal notranslate\">formfield()</code></a> メソッドは次のように書けます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">formfield</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"c1\"># This is a fairly standard way to set up some defaults</span>\n        <span class=\"c1\"># while letting the caller override them.</span>\n        defaults <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form_class&quot;</span><span class=\"p\">:</span> MyFormField<span class=\"p\">}</span>\n        defaults<span class=\"o\">.</span>update<span class=\"p\">(</span>kwargs<span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>formfield<span class=\"p\">(</span><span class=\"o\">**</span>defaults<span class=\"p\">)</span>\n</code></pre></div>\n<p>これは <code class=\"docutils literal notranslate\">MyFormField</code> フィールドクラス (デフォルトのウィジェットを持ちます) のインポートを想定しています。このドキュメントでは、カスタムフォームフィールドの書き方の詳細は説明しません。</p>\n</section>\n<section id=\"emulating-built-in-field-types\">\n<span id=\"id6\"></span><h4>組み込みフィールド・タイプのエミュレート<a class=\"heading-anchor\" href=\"#emulating-built-in-field-types\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>もし <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> メソッドを作成したのなら、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_internal_type\" title=\"django.db.models.Field.get_internal_type\"><code class=\"xref py py-meth docutils literal notranslate\">get_internal_type()</code></a> はあまり使わないので気にしなくても大丈夫です。しかし、データベースストレージの型は他のフィールドと似ていることがあるので、正しいカラムを作成するために他のフィールドのロジックを使うこともできます。</p>\n<p>例えば:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_internal_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"s2\">&quot;CharField&quot;</span>\n</code></pre></div>\n<p>どのデータベースのバックエンドを使用していても、<a class=\"reference internal\" href=\"/ja/5.0/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> やその他のSQLコマンドは文字列を格納するための正しいカラムタイプを作成します。</p>\n<p>もし <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.get_internal_type\" title=\"django.db.models.Field.get_internal_type\"><code class=\"xref py py-meth docutils literal notranslate\">get_internal_type()</code></a> が、使用しているデータベースのバックエンドで Django が知らない文字列 (つまり、<code class=\"docutils literal notranslate\">django.db.backends.&lt;db_name&gt;.base.DatabaseWrapper.data_types</code> にない文字列) を返した場合、シリアライザはその文字列を使用しますが、デフォルトの <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> メソッドは <code class=\"docutils literal notranslate\">None</code> を返します。これが便利な理由は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.db_type\" title=\"django.db.models.Field.db_type\"><code class=\"xref py py-meth docutils literal notranslate\">db_type()</code></a> のドキュメントを参照してください。シリアライザのフィールドの型として説明的な文字列を入れるのは、シリアライザの出力を Django 以外の他の場所で使う場合に便利なアイデアです。</p>\n</section>\n<section id=\"converting-field-data-for-serialization\">\n<span id=\"converting-model-field-to-serialization\"></span><h4>シリアライズするためにフィールドデータを変換する場合<a class=\"heading-anchor\" href=\"#converting-field-data-for-serialization\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>シリアライザによる値のシリアライズ方法をカスタマイズするには、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.value_to_string\" title=\"django.db.models.Field.value_to_string\"><code class=\"xref py py-meth docutils literal notranslate\">value_to_string()</code></a> をオーバーライドします。 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/fields/#django.db.models.Field.value_from_object\" title=\"django.db.models.Field.value_from_object\"><code class=\"xref py py-meth docutils literal notranslate\">value_from_object()</code></a> を使うのは、シリアライズの前にフィールドの値を取得する最も良い方法です。例えば、 <code class=\"docutils literal notranslate\">HandField</code> はデータの保存に文字列を使うので、既存の変換コードを再利用できます:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">HandField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">value_to_string</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> obj<span class=\"p\">):</span>\n        value <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>value_from_object<span class=\"p\">(</span>obj<span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>get_prep_value<span class=\"p\">(</span>value<span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"some-general-advice\">\n<h3>一般的なアドバイス<a class=\"heading-anchor\" href=\"#some-general-advice\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>カスタムフィールドの作成は、特に Python の型とデータベースやシリアライズのフォーマットとの間で複雑な変換を行う場合、厄介なプロセスになることがあります。ここでは、スムーズに進めるためのヒントをいくつか紹介します:</p>\n<ol class=\"arabic simple\">\n<li><p>既存の Django フィールド ( <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/5.0.x/django/db/models/fields/__init__.py\">django/db/models/fields/__init__.py</a> にあります) を見て、着想を得てください。ゼロから全く新しいフィールドを作るのではなく、あなたの欲しいものに似たフィールドを見つけ、それを少し拡張してみてください。</p></li>\n<li><p>フィールドとしてラップしているクラスに <code class=\"docutils literal notranslate\">__str__()</code> メソッドを追加します。フィールドのコードのデフォルトの動作として、値に対して <code class=\"docutils literal notranslate\">str()</code> を呼び出す箇所が多くあります。(このドキュメントの例では、 <code class=\"docutils literal notranslate\">value</code> は <code class=\"docutils literal notranslate\">HandField</code> ではなく <code class=\"docutils literal notranslate\">Hand</code> インスタンスになります）。そのため、 <code class=\"docutils literal notranslate\">__str__()</code> メソッドが自動的に Python オブジェクトの文字列形式に変換してくれれば、多くの手間を省けます。</p></li>\n</ol>\n</section>\n</section>\n<section id=\"writing-a-filefield-subclass\">\n<h2><code class=\"docutils literal notranslate\">FileField</code> サブクラスを書く<a class=\"heading-anchor\" href=\"#writing-a-filefield-subclass\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>上記のメソッドに加えて、ファイルを扱うフィールドには考慮すべき特別な要件がいくつかあります。 <code class=\"docutils literal notranslate\">FileField</code> によって提供される仕組みの大部分、例えばデータベースの保存と取得の制御などは、変更することなく、サブクラスに特定のタイプのファイルをサポートさせることができます。</p>\n<p>Django は <code class=\"docutils literal notranslate\">File</code> クラスを提供し、ファイルの内容や操作のプロキシとして使われます。これをサブクラス化することで、ファイルへのアクセス方法や利用可能なメソッドをカスタマイズできます。このクラスは <code class=\"docutils literal notranslate\">django.db.models.fields.files</code> にあり、デフォルトの動作は <a class=\"reference internal\" href=\"/ja/5.0/ref/files/file/\"><span class=\"doc\">ファイルのドキュメント</span></a> で解説しています。</p>\n<p>一度 <code class=\"docutils literal notranslate\">File</code> のサブクラスが作成されると、新しい <code class=\"docutils literal notranslate\">FileField</code> サブクラスにはそれを使用するように指示する必要があります。そのためには、新しい <code class=\"docutils literal notranslate\">File</code> サブクラスを <code class=\"docutils literal notranslate\">FileField</code> サブクラスの特別な <code class=\"docutils literal notranslate\">attr_class</code> 属性に割り当てます。</p>\n<section id=\"a-few-suggestions\">\n<h3>いくつかの提案<a class=\"heading-anchor\" href=\"#a-few-suggestions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>上記の詳細に加えて、フィールドのコードの効率と読みやすさを劇的に改善するいくつかのガイドラインがあります。</p>\n<ol class=\"arabic simple\">\n<li><p>Django 独自の <code class=\"docutils literal notranslate\">ImageField</code> のソース ( <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/5.0.x/django/db/models/fields/files.py\">django/db/models/fields/files.py</a> ) は、上で説明したテクニックを全て組み込んでいるので、特定のファイルタイプをサポートするために <code class=\"docutils literal notranslate\">FileField</code> をサブクラス化する方法の良い例です。</p></li>\n<li><p>できるだけファイル属性をキャッシュします。ファイルはリモートのストレージシステムに保存されている可能性があるため、それらを取得するには、必ずしも必要ではない余分な時間やコストがかかる可能性があります。一度ファイルを検索してその内容に関するデータを取得したら、そのデータをできるだけ多くキャッシュして、その情報を取得するために以後ファイルを検索する回数を減らします。</p></li>\n</ol>\n</section>\n</section>","rootId":"how-to-create-custom-model-fields","toc":[{"title":"はじめに","anchor":"introduction","children":[{"title":"私たちのサンプルオブジェクト","anchor":"our-example-object","children":[]}]},{"title":"背景理論","anchor":"background-theory","children":[{"title":"データベースストレージ","anchor":"database-storage","children":[]},{"title":"フィールドクラスが行うこと","anchor":"what-does-a-field-class-do","children":[]}]},{"title":"フィールドサブクラスを書く","anchor":"writing-a-field-subclass","children":[{"title":"フィールドの解体","anchor":"field-deconstruction","children":[]},{"title":"データベースのカラム定義に影響しないフィールド属性","anchor":"field-attributes-not-affecting-database-column-definition","children":[]},{"title":"カスタムフィールドのベースクラスを変更する","anchor":"changing-a-custom-field-s-base-class","children":[]},{"title":"カスタムフィールドのドキュメントを書く","anchor":"documenting-your-custom-field","children":[]},{"title":"便利なメソッド","anchor":"useful-methods","children":[{"title":"カスタムデータベースタイプ","anchor":"custom-database-types","children":[]},{"title":"変数を Python オブジェクトに変換する","anchor":"converting-values-to-python-objects","children":[]},{"title":"Python オブジェクトをクエリ変数に変換する","anchor":"converting-python-objects-to-query-values","children":[]},{"title":"クエリの変数をデータベースの変数に変換する","anchor":"converting-query-values-to-database-values","children":[]},{"title":"保存する前に値を前処理する場合","anchor":"preprocessing-values-before-saving","children":[]},{"title":"モデルフィールドのフォームフィールドの指定","anchor":"specifying-the-form-field-for-a-model-field","children":[]},{"title":"組み込みフィールド・タイプのエミュレート","anchor":"emulating-built-in-field-types","children":[]},{"title":"シリアライズするためにフィールドデータを変換する場合","anchor":"converting-field-data-for-serialization","children":[]}]},{"title":"一般的なアドバイス","anchor":"some-general-advice","children":[]}]},{"title":"FileField サブクラスを書く","anchor":"writing-a-filefield-subclass","children":[{"title":"いくつかの提案","anchor":"a-few-suggestions","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"「How-to」ガイド","url":"/ja/5.0/howto/"}],"prev":{"docname":"howto/custom-management-commands","title":"カスタム django-admin コマンドの作り方","url":"/ja/5.0/howto/custom-management-commands/"},"next":{"docname":"howto/custom-lookups","title":"カスタムのルックアップを書く","url":"/ja/5.0/howto/custom-lookups/"},"formats":{"html":"/ja/5.0/howto/custom-model-fields/","markdown":"/ja/5.0/howto/custom-model-fields.md","json":"/ja/5.0/howto/custom-model-fields.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/howto/custom-model-fields.txt","official":"https://docs.djangoproject.com/ja/5.0/howto/custom-model-fields/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}