{"title":"Django オブジェクトのシリアライズ","version":"5.1","locale":"ja","docname":"topics/serialization","url":"/ja/5.1/topics/serialization/","canonical":"https://djangodocs.dev/ja/5.1/topics/serialization/","summary":"Django のシリアライズフレームワークは、Django のモデルを他のフォーマットに「翻訳」する仕組みを提供します。通常、このような他のフォーマットはテキストベースや Django データをネットワーク越しに送信するために使われるフォーマットになりますが、シリアライザーはどんなフォーマットも…","html":"<h1>Django オブジェクトのシリアライズ<a class=\"heading-anchor\" href=\"#serializing-django-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django のシリアライズフレームワークは、Django のモデルを他のフォーマットに「翻訳」する仕組みを提供します。通常、このような他のフォーマットはテキストベースや Django データをネットワーク越しに送信するために使われるフォーマットになりますが、シリアライザーはどんなフォーマットも (テキストベースと非テキストベースのいずれも) 処理可能です。</p>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">参考</p>\n<p>あるデータをテーブルからシリアライズされた形式として取得したい場合、<a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dumpdata</span></code></a> 管理コマンドが使用できます。</p>\n</aside>\n<section id=\"serializing-data\">\n<h2>データのシリアライズ<a class=\"heading-anchor\" href=\"#serializing-data\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">serializers</span>\n\n<span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">SomeModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">())</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">serialize</span></code> 関数の引数は、データをシリアライズするフォーマット (<a class=\"reference internal\" href=\"#id2\">シリアライズフォーマット</a>) とシリアライズする <a class=\"reference internal\" href=\"/ja/5.1/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code></a> です。(実際、第2引数は Django モデルのインスタンスを yield するどんなイテレータでも渡せますが、ほとんど場合は QuerySet になります。)</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.core.serializers.get_serializer\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.serializers.</span></span><span class=\"sig-name descname\"><span class=\"pre\">get_serializer</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">format</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.serializers.get_serializer\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\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=\"n\">XMLSerializer</span> <span class=\"o\">=</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">get_serializer</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">)</span>\n<span class=\"n\">xml_serializer</span> <span class=\"o\">=</span> <span class=\"n\">XMLSerializer</span><span class=\"p\">()</span>\n<span class=\"n\">xml_serializer</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"n\">queryset</span><span class=\"p\">)</span>\n<span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">xml_serializer</span><span class=\"o\">.</span><span class=\"n\">getvalue</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>これは次のようにデータをファイルライクなオブジェクト (<a class=\"reference internal\" href=\"/ja/5.1/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></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\">with</span> <span class=\"nb\">open</span><span class=\"p\">(</span><span class=\"s2\">&quot;file.xml&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;w&quot;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"n\">out</span><span class=\"p\">:</span>\n    <span class=\"n\">xml_serializer</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"n\">SomeModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">(),</span> <span class=\"n\">stream</span><span class=\"o\">=</span><span class=\"n\">out</span><span class=\"p\">)</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p><a class=\"reference internal\" href=\"#django.core.serializers.get_serializer\" title=\"django.core.serializers.get_serializer\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">get_serializer()</span></code></a> を未知の <a class=\"reference internal\" href=\"#serialization-formats\"><span class=\"std std-ref\">フォーマット</span></a> で呼び出すと、<code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.serializers.SerializerDoesNotExist</span></code> 例外が発生します。</p>\n</aside>\n<section id=\"subset-of-fields\">\n<span id=\"id1\"></span><h3>フィールドのサブセット<a class=\"heading-anchor\" href=\"#subset-of-fields\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>フィールドのサブセットのみをシリアライズしたい場合は、次のようにシリアライザーに <code class=\"docutils literal notranslate\"><span class=\"pre\">fields</span></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=\"w\"> </span><span class=\"nn\">django.core</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">serializers</span>\n\n<span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">SomeModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">(),</span> <span class=\"n\">fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;size&quot;</span><span class=\"p\">])</span>\n</code></pre></div>\n<p>この例では、各モデルの <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">size</span></code> 属性だけがシリアライズされます。プライマリキーは常に出力結果内の <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code> 要素としてシリアライズされ、<code class=\"docutils literal notranslate\"><span class=\"pre\">fields</span></code> 部分には決して現れません。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>モデルによってはフィールドのサブセットだけをシリアライズしたモデルをデシリアライズすることは不可能かもしれません。もしシリアライズしたオブジェクトがモデルで必須のすべてのフィールドを指定しなかった場合、デシリアライザーはデシリアライズされたインスタンスを保存できないでしょう。</p>\n</aside>\n</section>\n<section id=\"inherited-models\">\n<h3>継承されたモデル<a class=\"heading-anchor\" href=\"#inherited-models\"><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.1/topics/db/models/#abstract-base-classes\"><span class=\"std std-ref\">抽象ベースクラス</span></a> を使用して定義したモデルの場合、そのモデルをシリアライズするために特別なことは何もする必要がありません。シリアライズしたいオブジェクト (または複数のオブジェクト) 上でシリアライザーを呼べば、出力はシリアライズされたオブジェクトの完全な表現になります。</p>\n<p>しかし、<a class=\"reference internal\" href=\"/ja/5.1/topics/db/models/#multi-table-inheritance\"><span class=\"std std-ref\">マルチテーブル継承</span></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=\"w\"> </span><span class=\"nc\">Place</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Restaurant</span><span class=\"p\">(</span><span class=\"n\">Place</span><span class=\"p\">):</span>\n    <span class=\"n\">serves_hot_dogs</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">BooleanField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>もし次のように Reastaurant モデルだけをシリアライズした場合、</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=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">Restaurant</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">())</span>\n</code></pre></div>\n<p>シリアライズされた出力のフィールドには、<code class=\"docutils literal notranslate\"><span class=\"pre\">serves_hot_dogs</span></code> 属性だけが含まれます。ベースクラスの <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> 属性は無視されます。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Restaurant</span></code> インスタンスを完全にシリアライズするためには、<code class=\"docutils literal notranslate\"><span class=\"pre\">Place</span></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=\"n\">all_objects</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"o\">*</span><span class=\"n\">Restaurant</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">(),</span> <span class=\"o\">*</span><span class=\"n\">Place</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()]</span>\n<span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">all_objects</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"deserializing-data\">\n<h2>データのデシリアライズ<a class=\"heading-anchor\" href=\"#deserializing-data\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\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\">for</span> <span class=\"n\">obj</span> <span class=\"ow\">in</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">deserialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">):</span>\n    <span class=\"n\">do_something_with</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>見ての通り、<code class=\"docutils literal notranslate\"><span class=\"pre\">deserialize</span></code> 関数は、<code class=\"docutils literal notranslate\"><span class=\"pre\">serialize</span></code> と同じ形式の引数であるデータの文字列またはストリームを取り、イテレータを返します。</p>\n<p>しかし、ここで処理は少し複雑になります。<code class=\"docutils literal notranslate\"><span class=\"pre\">deserialize</span></code> イテレータによって返されるオブジェクトは、通常の Django オブジェクト <em>ではありません</em>。代わりに、作成された (ただし、保存されていない) オブジェクトと関連するリレーションデータをラップした、特別な <code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializedObject</span></code> インスタンスです。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializedObject.save()</span></code> を呼ぶと、オブジェクトはデータベースに保存されます。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>もしシリアライズされたデータ内に <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code> 属性が存在しないか、null だった場合、新しいインスタンスがデータベースに保存されます。</p>\n</aside>\n<p>これにより、もしシリアライズされた表現内のデータが現在データベース内にあるデータと一致しなかったとしても、デシリアライズ処理は非破壊的な操作であることが保証されます。通常、<code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializedObject</span></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\">for</span> <span class=\"n\">deserialized_object</span> <span class=\"ow\">in</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">deserialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">object_should_be_saved</span><span class=\"p\">(</span><span class=\"n\">deserialized_object</span><span class=\"p\">):</span>\n        <span class=\"n\">deserialized_object</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>言い換えれば、通常の使用では、デシリアライズされたオブジェクトが保存する前に保存するのに「適している」ことを確認します。もしデータソースを信頼しているなら、代わりにオブジェクトを直接保存してそのまま先に進めます。</p>\n<p>Django オブジェクト自体は、<code class=\"docutils literal notranslate\"><span class=\"pre\">deserialized_object.object</span></code> として検査できます。シリアライズされたデータ内のフィールドがモデル上に存在しない場合は、<code class=\"docutils literal notranslate\"><span class=\"pre\">ignorenonexistent</span></code> 引数に <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> が渡されていない限り、<code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializationError</span></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=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">deserialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">ignorenonexistent</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"serialization-formats\">\n<span id=\"id2\"></span><h2>シリアライズフォーマット<a class=\"heading-anchor\" href=\"#serialization-formats\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django は多数のシリアライズフォーマットをサポートしてします。一部のフォーマットはサードパーティの Python モジュールが必要です。</p>\n<div class=\"table-scroll\" role=\"region\" tabindex=\"0\" aria-label=\"Table\"><table class=\"docutils align-default\">\n<thead>\n<tr class=\"row-odd\"><th class=\"head\"><p>識別子</p></th>\n<th class=\"head\"><p>情報</p></th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\"><span class=\"pre\">xml</span></code></p></td>\n<td><p>シンプルな XML 方言のシリアライズ・デシリアライズを行います。</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\"><span class=\"pre\">json</span></code></p></td>\n<td><p><a class=\"reference external\" href=\"https://json.org/\">JSON</a> のシリアライズ・デシリアライズを行います。</p></td>\n</tr>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\"><span class=\"pre\">jsonl</span></code></p></td>\n<td><p><a class=\"reference external\" href=\"https://jsonlines.org/\">JSONL</a> のシリアライズ・デシリアライズを行います。</p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\"><span class=\"pre\">yaml</span></code></p></td>\n<td><p>YAML (YAML Ain't a Markup Language) のシリアライズ・デシリアライズを行います。このシリアライザーは <a class=\"reference external\" href=\"https://pyyaml.org/\">PyYAML</a> がインストールされている場合のみ利用できます。</p></td>\n</tr>\n</tbody>\n</table>\n</div>\n<section id=\"xml\">\n<span id=\"serialization-formats-xml\"></span><h3>XML<a class=\"heading-anchor\" href=\"#xml\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>基本的なXMLのシリアライズフォーマットは以下のようなものです:</p>\n<div class=\"code-block\" data-language=\"xml\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">XML</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=\"XML code\"><code><span class=\"cp\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>\n<span class=\"nt\">&lt;django-objects</span><span class=\"w\"> </span><span class=\"na\">version=</span><span class=\"s\">&quot;1.0&quot;</span><span class=\"nt\">&gt;</span>\n<span class=\"w\">    </span><span class=\"nt\">&lt;object</span><span class=\"w\"> </span><span class=\"na\">pk=</span><span class=\"s\">&quot;123&quot;</span><span class=\"w\"> </span><span class=\"na\">model=</span><span class=\"s\">&quot;sessions.session&quot;</span><span class=\"nt\">&gt;</span>\n<span class=\"w\">        </span><span class=\"nt\">&lt;field</span><span class=\"w\"> </span><span class=\"na\">type=</span><span class=\"s\">&quot;DateTimeField&quot;</span><span class=\"w\"> </span><span class=\"na\">name=</span><span class=\"s\">&quot;expire_date&quot;</span><span class=\"nt\">&gt;</span>2013-01-16T08:16:59.844560+00:00<span class=\"nt\">&lt;/field&gt;</span>\n<span class=\"w\">        </span><span class=\"cm\">&lt;!-- ... --&gt;</span>\n<span class=\"w\">    </span><span class=\"nt\">&lt;/object&gt;</span>\n<span class=\"nt\">&lt;/django-objects&gt;</span>\n</code></pre></div>\n<p>シリアライズまたはデシリアライズされたオブジェクトのコレクション全体は、複数の <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;object&gt;</span></code> 要素を含む <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;djangoobjects&gt;</span></code> タグで表現されます。このようなオブジェクトはそれぞれ2つの属性を持ちます。&quot;pk&quot; と &quot;model&quot; です。後者はアプリの名前 (&quot;sessions&quot;) とモデルの小文字の名前 (&quot;session&quot;) をドットで区切って表します。</p>\n<p>オブジェクトの各フィールドは &quot;type &quot;と &quot;name &quot;のフィールドを持つ <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;field&gt;</span></code> 要素としてシリアライズされます。要素のテキストコンテンツは格納されるべき値を表します。</p>\n<p>外部キーとその他のリレーション先フィールドは、少し違う扱いになります:</p>\n<div class=\"code-block\" data-language=\"xml\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">XML</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=\"XML code\"><code><span class=\"nt\">&lt;object</span><span class=\"w\"> </span><span class=\"na\">pk=</span><span class=\"s\">&quot;27&quot;</span><span class=\"w\"> </span><span class=\"na\">model=</span><span class=\"s\">&quot;auth.permission&quot;</span><span class=\"nt\">&gt;</span>\n<span class=\"w\">    </span><span class=\"cm\">&lt;!-- ... --&gt;</span>\n<span class=\"w\">    </span><span class=\"nt\">&lt;field</span><span class=\"w\"> </span><span class=\"na\">to=</span><span class=\"s\">&quot;contenttypes.contenttype&quot;</span><span class=\"w\"> </span><span class=\"na\">name=</span><span class=\"s\">&quot;content_type&quot;</span><span class=\"w\"> </span><span class=\"na\">rel=</span><span class=\"s\">&quot;ManyToOneRel&quot;</span><span class=\"nt\">&gt;</span>9<span class=\"nt\">&lt;/field&gt;</span>\n<span class=\"w\">    </span><span class=\"cm\">&lt;!-- ... --&gt;</span>\n<span class=\"nt\">&lt;/object&gt;</span>\n</code></pre></div>\n<p>この例では、PK 27の <code class=\"docutils literal notranslate\"><span class=\"pre\">auth.Permission</span></code> オブジェクトが、PK 9の <code class=\"docutils literal notranslate\"><span class=\"pre\">contenttypes.ContentType</span></code> インスタンスに対する外部キーを持つように指定しています。</p>\n<p>多対多のリレーションはそれらを結びつけるモデルに対してエクスポートされます。例えば、<code class=\"docutils literal notranslate\"><span class=\"pre\">auth.User</span></code> モデルは <code class=\"docutils literal notranslate\"><span class=\"pre\">auth.Permission</span></code> モデルに対してこのようなリレーションを持っています:</p>\n<div class=\"code-block\" data-language=\"xml\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">XML</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=\"XML code\"><code><span class=\"nt\">&lt;object</span><span class=\"w\"> </span><span class=\"na\">pk=</span><span class=\"s\">&quot;1&quot;</span><span class=\"w\"> </span><span class=\"na\">model=</span><span class=\"s\">&quot;auth.user&quot;</span><span class=\"nt\">&gt;</span>\n<span class=\"w\">    </span><span class=\"cm\">&lt;!-- ... --&gt;</span>\n<span class=\"w\">    </span><span class=\"nt\">&lt;field</span><span class=\"w\"> </span><span class=\"na\">to=</span><span class=\"s\">&quot;auth.permission&quot;</span><span class=\"w\"> </span><span class=\"na\">name=</span><span class=\"s\">&quot;user_permissions&quot;</span><span class=\"w\"> </span><span class=\"na\">rel=</span><span class=\"s\">&quot;ManyToManyRel&quot;</span><span class=\"nt\">&gt;</span>\n<span class=\"w\">        </span><span class=\"nt\">&lt;object</span><span class=\"w\"> </span><span class=\"na\">pk=</span><span class=\"s\">&quot;46&quot;</span><span class=\"nt\">&gt;&lt;/object&gt;</span>\n<span class=\"w\">        </span><span class=\"nt\">&lt;object</span><span class=\"w\"> </span><span class=\"na\">pk=</span><span class=\"s\">&quot;47&quot;</span><span class=\"nt\">&gt;&lt;/object&gt;</span>\n<span class=\"w\">    </span><span class=\"nt\">&lt;/field&gt;</span>\n<span class=\"nt\">&lt;/object&gt;</span>\n</code></pre></div>\n<p>この例では、与えられたユーザーをPK46と47を持つパーミッションモデルにリンクしています。</p>\n<aside class=\"admonition-control-characters admonition\">\n<p class=\"admonition-title\">制御文字</p>\n<p>シリアライズされるコンテンツにXML 1.0標準では認められていない制御文字が含まれている場合、 <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#ValueError\" title=\"(in Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">ValueError</span></code></a> 例外が発生してシリアライズは失敗します。詳しくはW3Cの <a class=\"reference external\" href=\"https://www.w3.org/International/questions/qa-controls\">HTML, XHTML, XML and Control Codes</a> の説明を参照してください。</p>\n</aside>\n</section>\n<section id=\"serialization-formats-json\">\n<span id=\"id3\"></span><h3>JSON<a class=\"heading-anchor\" href=\"#serialization-formats-json\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>以前と同じ例のデータを使うと、データは JSON として次のようにシリアライズされます。</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=\"p\">[</span>\n    <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;4b678b301dfd8a4e0dad910de3ae245b&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;sessions.session&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n            <span class=\"s2\">&quot;expire_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;2013-01-16T08:16:59.844Z&quot;</span><span class=\"p\">,</span>\n            <span class=\"c1\"># ...</span>\n        <span class=\"p\">},</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>このフォーマットは、XML よりも少しシンプルです。コレクション全体は array として表現され、オブジェクトは3つのプロパティ &quot;pk&quot;、&quot;model&quot;、&quot;fields&quot; を持つ JSON オブジェクトとして表現されています。&quot;fields&quot; もオブジェクトであり、各フィールド名と値がそれぞれプロパティとプロパティ値として含まれています。</p>\n<p>外部キーは、プロパティ値としてリンクされたオブジェクトの PK を持ちます。ManyToMany リレーションは、それを定義したモデルに対してシリアライズされ、PK のリストとして表現されます。</p>\n<p>すべての Django 出力が未修正のまま <a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#module-json\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">json</span></code></a> に渡せるとは限らないことに注意してください。たとえば、シリアライズするオブジェクトにカスタム型がある場合、そのためのカスタム <a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#module-json\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">json</span></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=\"w\"> </span><span class=\"nn\">django.core.serializers.json</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DjangoJSONEncoder</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">LazyEncoder</span><span class=\"p\">(</span><span class=\"n\">DjangoJSONEncoder</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">default</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"p\">,</span> <span class=\"n\">YourCustomType</span><span class=\"p\">):</span>\n            <span class=\"k\">return</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">default</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>そして、<code class=\"docutils literal notranslate\"><span class=\"pre\">cls=LazyEncoder</span></code> を <code class=\"docutils literal notranslate\"><span class=\"pre\">serializers.serialize()</span></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=\"w\"> </span><span class=\"nn\">django.core.serializers</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">serialize</span>\n\n<span class=\"n\">serialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;json&quot;</span><span class=\"p\">,</span> <span class=\"n\">SomeModel</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">(),</span> <span class=\"bp\">cls</span><span class=\"o\">=</span><span class=\"n\">LazyEncoder</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>GeoDjango は <a class=\"reference internal\" href=\"/ja/5.1/ref/contrib/gis/serializers/\"><span class=\"doc\">カスタマイズされた GeoJSON シリアライザー</span></a> を提供していることにも注意してください。</p>\n<section id=\"djangojsonencoder\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoJSONEncoder</span></code><a class=\"heading-anchor\" href=\"#djangojsonencoder\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.core.serializers.json.DjangoJSONEncoder\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">django.core.serializers.json.</span></span><span class=\"sig-name descname\"><span class=\"pre\">DjangoJSONEncoder</span></span><a class=\"heading-anchor\" href=\"#django.core.serializers.json.DjangoJSONEncoder\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>JSON シリアライザーは <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoJSONEncoder</span></code> をエンコーディングに使用します。<a class=\"reference external\" href=\"https://docs.python.org/3/library/json.html#json.JSONEncoder\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">JSONEncoder</span></code></a> のサブクラスであり、以下の追加の型を処理します。</p>\n<dl class=\"simple\">\n<dt><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.datetime\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">datetime</span></code></a></dt><dd><p><a class=\"reference external\" href=\"https://262.ecma-international.org/5.1/#sec-15.9.1.15\">ECMA-262</a> で定義されている <code class=\"docutils literal notranslate\"><span class=\"pre\">YYYY-MM-DDTHH:mm:ss.sssZ</span></code> または <code class=\"docutils literal notranslate\"><span class=\"pre\">YYYY-MM-DDTHH:mm:ss.sss+HH:MM</span></code> という形式の文字列。</p>\n</dd>\n<dt><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.date\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">date</span></code></a></dt><dd><p><code class=\"docutils literal notranslate\"><span class=\"pre\">YYYY-MM-DD</span></code> という形式の文字列は、<a class=\"reference external\" href=\"https://262.ecma-international.org/5.1/#sec-15.9.1.15\">ECMA-262</a> で定義されています。</p>\n</dd>\n<dt><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.time\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">time</span></code></a></dt><dd><p><code class=\"docutils literal notranslate\"><span class=\"pre\">HH:MM:ss.sss</span></code> という形式の文字列は、<a class=\"reference external\" href=\"https://262.ecma-international.org/5.1/#sec-15.9.1.15\">ECMA-262</a> で定義されています。</p>\n</dd>\n<dt><a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#datetime.timedelta\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">timedelta</span></code></a></dt><dd><p>期間を表現する文字列は ISO-8601 で定義されています。たとえば、<code class=\"docutils literal notranslate\"><span class=\"pre\">timedelta(days=1,</span> <span class=\"pre\">hours=2,</span> <span class=\"pre\">seconds=3.4)</span></code> は <code class=\"docutils literal notranslate\"><span class=\"pre\">'P1DT02H00M03.400000S'</span></code> と表現されます。</p>\n</dd>\n<dt><a class=\"reference external\" href=\"https://docs.python.org/3/library/decimal.html#decimal.Decimal\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Decimal</span></code></a>, <code class=\"docutils literal notranslate\"><span class=\"pre\">Promise</span></code> (<code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.functional.lazy()</span></code> objects), <a class=\"reference external\" href=\"https://docs.python.org/3/library/uuid.html#uuid.UUID\" title=\"(in Python v3.14)\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UUID</span></code></a></dt><dd><p>オブジェクトの文字列表現です。</p>\n</dd>\n</dl>\n</section>\n</section>\n<section id=\"serialization-formats-jsonl\">\n<span id=\"id4\"></span><h3>JSONL<a class=\"heading-anchor\" href=\"#serialization-formats-jsonl\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><em>JSONL</em> は <em>JSON Lines</em> の略です。このフォーマットでは、オブジェクトは改行で区切られ、各行には有効なJSONオブジェクトが含まれます。JSONLでシリアライズされたデータは次のようになります:</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=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;4b678b301dfd8a4e0dad910de3ae245b&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;sessions.session&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">}}</span>\n<span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;88bea72c02274f3c9bf1cb2bb8cee4fc&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;sessions.session&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">}}</span>\n<span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;9cf0e26691b64147a67e2a9f06ad7a53&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;sessions.session&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">}}</span>\n</code></pre></div>\n<p>JSONLは、データを一度にメモリに読み込むのではなく、一行ずつ処理できるため、大規模なデータベースにデータを入力するのに便利です。</p>\n</section>\n<section id=\"yaml\">\n<h3>YAML<a class=\"heading-anchor\" href=\"#yaml\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>YAML シリアライズは JSON にとてもよく似ています。オブジェクトリストは &quot;pk&quot;、&quot;model&quot;、&quot;fields&quot; を持つマッピングのシーケンスとしてシリアライズされます。各フィールドもマッピングで、キーがフィールド名、値が値になります。</p>\n<div class=\"code-block\" data-language=\"yaml\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">YAML</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=\"YAML code\"><code><span class=\"p p-Indicator\">-</span><span class=\"w\"> </span><span class=\"nt\">model</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"l l-Scalar l-Scalar-Plain\">sessions.session</span>\n<span class=\"w\">  </span><span class=\"nt\">pk</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"l l-Scalar l-Scalar-Plain\">4b678b301dfd8a4e0dad910de3ae245b</span>\n<span class=\"w\">  </span><span class=\"nt\">fields</span><span class=\"p\">:</span>\n<span class=\"w\">    </span><span class=\"nt\">expire_date</span><span class=\"p\">:</span><span class=\"w\"> </span><span class=\"l l-Scalar l-Scalar-Plain\">2013-01-16 08:16:59.844560+00:00</span>\n</code></pre></div>\n<p>参照フィールドは、同様に PK または PK のシーケンスとして表現されます。</p>\n</section>\n</section>\n<section id=\"natural-keys\">\n<span id=\"topics-serialization-natural-keys\"></span><h2>ナチュラルキー<a class=\"heading-anchor\" href=\"#natural-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>デフォルトの外部キーと多対多リレーションのシリアライズ戦略は、オブジェクトのプライマリーキーの値をリレーション内にシリアライズするというものです。この戦略はほとんどのオブジェクトに対してうまく機能しますが、いくつかの状況で困難を引き起こします。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentType\" title=\"django.contrib.contenttypes.models.ContentType\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ContentType</span></code></a> を参照する外部キーを持つオブジェクトのリストの場合を考えてみてください。もしcontent type を参照するオブジェクトをシリアライズしようとした場合、最初に content type を参照する手段が必要になります。<code class=\"docutils literal notranslate\"><span class=\"pre\">ContentType</span></code> オブジェクトは Django がデータベースの同期処理の間に自動的に作成するため、与えられた content type のプライマリーキーは簡単には予測できず、<a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">migrate</span></code></a> が実行される方法とタイミングに依存することになってしまいます。同じことは、特に <a class=\"reference internal\" href=\"/ja/5.1/ref/contrib/auth/#django.contrib.auth.models.Permission\" title=\"django.contrib.auth.models.Permission\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Permission</span></code></a>、<a class=\"reference internal\" href=\"/ja/5.1/ref/contrib/auth/#django.contrib.auth.models.Group\" title=\"django.contrib.auth.models.Group\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Group</span></code></a>、<a class=\"reference internal\" href=\"/ja/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> を含む、オブジェクトを自動生成するすべてのモデルにも当てはまります。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>自動生成されたオブジェクトは、決してフィクスチャや他のシリアライズされたデータに含めるべきではありません。偶然、フィクスチャ内のプライマリーキーがデータベース内のものと一致して、フィクスチャの読み込みに効果がないかもしれません。より起こりえる状況はプライマリーキーが一致しなかった場合で、フィクスチャのロードは <a class=\"reference internal\" href=\"/ja/5.1/ref/exceptions/#django.db.IntegrityError\" title=\"django.db.IntegrityError\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">IntegrityError</span></code></a> で失敗してしまいます。</p>\n</aside>\n<p>利便性の問題もあります。integer id というのは、必ずしもオブジェクトを参照するための最も便利な方法というわけではありません。ときには、より自然な (ナチュラルな) 参照が助けになることがあります。</p>\n<p>このような理由のために Django が提供しているのが、<em>ナチュラルキー (natural key)</em> です。ナチュラルキーは、オブジェクトのインスタンスをプライマリーキーの値を使用せずに一意に識別するために使える値のタプルです。</p>\n<section id=\"deserialization-of-natural-keys\">\n<h3>ナチュラルキーのデシリアライズ<a class=\"heading-anchor\" href=\"#deserialization-of-natural-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>次の2つのモデルを考えてみてください。</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n\n    <span class=\"n\">birthdate</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">UniqueConstraint</span><span class=\"p\">(</span>\n                <span class=\"n\">fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">],</span>\n                <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;unique_first_last_name&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">author</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Person</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>通常は、<code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> のシリアライズされたデータは、著者 (author) を参照するために整数を使うことになります。たとえば、JSON では、Book は次のようにシリアライズされるでしょう。</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=\"o\">...</span>\n<span class=\"p\">{</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;store.book&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Mostly Harmless&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;author&quot;</span><span class=\"p\">:</span> <span class=\"mi\">42</span><span class=\"p\">}}</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>これは、著者を参照するのに特に自然な方法とは言えません。著者のプライマリーキーの値を知っていなければなりませんし、しかも、プライマリーキーの値は安定していて予測可能でなければなりません。</p>\n<p>しかし、Person にナチュラルキーの処理を追加した場合、フィクスチャはもっとずっと人間によってわかりやすくなります。ナチュラルキーの処理を追加するには、Person のデフォルトの Manager を <code class=\"docutils literal notranslate\"><span class=\"pre\">get_by_natural_key()</span></code> を使用して定義します。Person の場合、よいナチュラルキーは、first name と last name のペアになるでしょう。</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=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PersonManager</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Manager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_by_natural_key</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"n\">last_name</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">first_name</span><span class=\"o\">=</span><span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"n\">last_name</span><span class=\"o\">=</span><span class=\"n\">last_name</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">birthdate</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">PersonManager</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">UniqueConstraint</span><span class=\"p\">(</span>\n                <span class=\"n\">fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">],</span>\n                <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;unique_first_last_name&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n</code></pre></div>\n<p>新しい本では、<code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></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=\"o\">...</span>\n<span class=\"p\">{</span>\n    <span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;store.book&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Mostly Harmless&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;author&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Douglas&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Adams&quot;</span><span class=\"p\">]},</span>\n<span class=\"p\">}</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>シリアライズされたデータをロードしようとするとき、Django は <code class=\"docutils literal notranslate\"><span class=\"pre\">get_by_natural_key()</span></code> メソッドを使って <code class=\"docutils literal notranslate\"><span class=\"pre\">[&quot;Douglas&quot;,</span> <span class=\"pre\">&quot;Adams&quot;]</span></code> を実際の <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> オブジェクトのプライマリーキーに解決します。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>ナチュラルキーに使用するフィールドは、オブジェクトを一意に識別できる必要があります。これは通常、モデルがナチュラルキーのフィールドや複数フィールドに対してユニーク制約 (単一フィールドに対する <code class=\"docutils literal notranslate\"><span class=\"pre\">unique=True</span></code>、または複数フィールドにわたる <code class=\"docutils literal notranslate\"><span class=\"pre\">UniqueConstraint</span></code> や <code class=\"docutils literal notranslate\"><span class=\"pre\">unique_together</span></code>) を持つことを意味します。しかし、一意性がデータベースレベルで強制される必要はありません。一連のフィールドが実際に一意であるという確信がある場合は、それらのフィールドをナチュラルキーとして使用できます。</p>\n</aside>\n<p>プライマリーキーがないオブジェクトのデシリアライズには、モデルのマネージャに <code class=\"docutils literal notranslate\"><span class=\"pre\">get_by_natural_key()</span></code> メソッドがあるかどうかを常にチェックします。ある場合は、これを使用して、デシリアライズされるオブジェクトのプライマリーキーを設定します。</p>\n</section>\n<section id=\"serialization-of-natural-keys\">\n<h3>ナチュラルキーのシリアライズ<a class=\"heading-anchor\" href=\"#serialization-of-natural-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>それでは、オブジェクトをシリアライズするときに、Django にナチュラルキーを発行させるにはどうすればいいのでしょうか？ はじめに、もう1つのメソッドを追加する必要があります。今回は、次のようにモデル自体に追加します。</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=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">last_name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">birthdate</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">PersonManager</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">UniqueConstraint</span><span class=\"p\">(</span>\n                <span class=\"n\">fields</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">],</span>\n                <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;unique_first_last_name&quot;</span><span class=\"p\">,</span>\n            <span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">natural_key</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">first_name</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">last_name</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>メソッドは、常にナチュラルキーの他ルプを返す必要があります。この例では、<code class=\"docutils literal notranslate\"><span class=\"pre\">(first</span> <span class=\"pre\">name,</span> <span class=\"pre\">last</span> <span class=\"pre\">name)</span></code> です。そして、<code class=\"docutils literal notranslate\"><span class=\"pre\">serializers.serialize()</span></code> を呼ぶときに、<code class=\"docutils literal notranslate\"><span class=\"pre\">use_natural_foreign_keys=True</span></code> または <code class=\"docutils literal notranslate\"><span class=\"pre\">use_natural_primary_keys=True</span></code> 引数を提供します。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</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=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">serialize</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;json&quot;</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"p\">[</span><span class=\"n\">book1</span><span class=\"p\">,</span> <span class=\"n\">book2</span><span class=\"p\">],</span>\n<span class=\"gp\">... </span>    <span class=\"n\">indent</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">use_natural_foreign_keys</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span>    <span class=\"n\">use_natural_primary_keys</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">use_natural_foreign_keys=True</span></code> が指定されたときは、Django は <code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> メソッドを使用して、メソッドを定義している型のオブジェクトへの外部キーの参照をシリアライズします。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">use_natural_primary_keys=True</span></code> が指定されたときは、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=\"o\">...</span>\n<span class=\"p\">{</span>\n    <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;store.person&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Douglas&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Adams&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;birth_date&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;1952-03-11&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">},</span>\n<span class=\"p\">}</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>これは、シリアライズされたデータを既存のデータベースに読み込む必要があり、シリアライズされたプライマリキーの値がすでに使用されていないことを保証できず、デシリアライズされたオブジェクトが同じプライマリキーを保持していることを保証する必要がない場合に便利です。</p>\n<p><a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dumpdata</span></code></a> を使用してシリアライズデータを生成する場合は、 <a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#cmdoption-dumpdata-natural-foreign\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">dumpdata</span> <span class=\"pre\">--natural-foreign</span></code></a> と <a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#cmdoption-dumpdata-natural-primary\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">dumpdata</span> <span class=\"pre\">--natural-primary</span></code></a> コマンドラインフラグを使用してナチュラルキーを生成します。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">get_by_natural_key()</span></code> の両方を定義する必要はありません。もし Django にシリアライズ時にナチュラルキーを出力させたくないが、 ナチュラルキーを読み込む機能は残しておきたい場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> メソッドを実装しなくても構いません。</p>\n<p>逆に、（特別な理由で）Django にシリアライズ時にナチュラルキーを出力させたいが、そのキーの値を読み込ませたく <em>ない</em> 場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">get_by_natural_key()</span></code> メソッドを定義しなければいいだけです。</p>\n</aside>\n</section>\n<section id=\"natural-keys-and-forward-references\">\n<span id=\"id5\"></span><h3>ナチュラルキーと前方参照<a class=\"heading-anchor\" href=\"#natural-keys-and-forward-references\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"#topics-serialization-natural-keys\"><span class=\"std std-ref\">ナチュラル外部キー</span></a> を使用するとき、データをシリアライズする必要があるけれども、オブジェクトの外部キーが参照している他のオブジェクトが、まだシリアライズされていないような場合があります。このことを「前方参照 (forward reference)」と呼びます。</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=\"o\">...</span>\n<span class=\"p\">{</span>\n    <span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;store.book&quot;</span><span class=\"p\">,</span>\n    <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Mostly Harmless&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;author&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;Douglas&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Adams&quot;</span><span class=\"p\">]},</span>\n<span class=\"p\">},</span>\n<span class=\"o\">...</span>\n<span class=\"p\">{</span><span class=\"s2\">&quot;model&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;store.person&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span><span class=\"s2\">&quot;first_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Douglas&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;last_name&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;Adams&quot;</span><span class=\"p\">}},</span>\n<span class=\"o\">...</span>\n</code></pre></div>\n<p>この状況を処理するには、<code class=\"docutils literal notranslate\"><span class=\"pre\">serializers.deserialize()</span></code> に <code class=\"docutils literal notranslate\"><span class=\"pre\">handle_forward_references=True</span></code> を渡す必要があります。これにより、<code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializedObject</span></code> インスタンスに <code class=\"docutils literal notranslate\"><span class=\"pre\">deferred_fields</span></code> 属性が設定されます。この属性が <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> ではない <code class=\"docutils literal notranslate\"><span class=\"pre\">DeserializedObject</span></code> インスタンスを追跡して、後でそれらに対して <code class=\"docutils literal notranslate\"><span class=\"pre\">save_deferred_fields()</span></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=\"n\">objs_with_deferred_fields</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n<span class=\"k\">for</span> <span class=\"n\">obj</span> <span class=\"ow\">in</span> <span class=\"n\">serializers</span><span class=\"o\">.</span><span class=\"n\">deserialize</span><span class=\"p\">(</span><span class=\"s2\">&quot;xml&quot;</span><span class=\"p\">,</span> <span class=\"n\">data</span><span class=\"p\">,</span> <span class=\"n\">handle_forward_references</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n    <span class=\"k\">if</span> <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">deferred_fields</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n        <span class=\"n\">objs_with_deferred_fields</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">obj</span><span class=\"p\">)</span>\n\n<span class=\"k\">for</span> <span class=\"n\">obj</span> <span class=\"ow\">in</span> <span class=\"n\">objs_with_deferred_fields</span><span class=\"p\">:</span>\n    <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save_deferred_fields</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>これが機能するには、参照しているモデル上の <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code> に <code class=\"docutils literal notranslate\"><span class=\"pre\">null=True</span></code> が設定されている必要があります。</p>\n</section>\n<section id=\"dependencies-during-serialization\">\n<h3>シリアライズ中の依存関係<a class=\"heading-anchor\" href=\"#dependencies-during-serialization\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>フィクスチャ内のオブジェクトの順番に注意することで、明示的に前方参照を扱わずに済むことがよくあります。</p>\n<p>これを支援するために、 <a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#cmdoption-dumpdata-natural-foreign\"><code class=\"xref std std-option docutils literal notranslate\"><span class=\"pre\">dumpdata</span> <span class=\"pre\">--natural-foreign</span></code></a> オプションを使用して <a class=\"reference internal\" href=\"/ja/5.1/ref/django-admin/#django-admin-dumpdata\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">dumpdata</span></code></a> を呼び出すと、標準のプライマリキーオブジェクトをシリアライズする前に、<code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> メソッドを持つ任意のモデルがシリアライズされます。</p>\n<p>しかし、これは必ずしも十分とは限りません。ナチュラルキーが別のオブジェクトを参照する場合 (ナチュラルキーの一部として外部キーまたは別のオブジェクトへのナチュラルキーを使用する場合)、ナチュラルキーが依存するオブジェクトが、ナチュラルキーが要求する前にシリアライズされたデータ内に存在することを保証できる必要があります。</p>\n<p>この順序を制御するには、 <code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> メソッドに依存関係を定義します。これは <code class=\"docutils literal notranslate\"><span class=\"pre\">natural_key()</span></code> メソッド自体に <code class=\"docutils literal notranslate\"><span class=\"pre\">dependencies</span></code> 属性を設定することで行います。</p>\n<p>たとえば、上の例の <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></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=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">author</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Person</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">natural_key</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,)</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">author</span><span class=\"o\">.</span><span class=\"n\">natural_key</span><span class=\"p\">()</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> のナチュラルキーは名前と著者の組み合わせです。つまり、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> は <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> の前にシリアライズされなければなりません。この依存関係を定義するために、1行追加します:</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=\"w\"> </span><span class=\"nf\">natural_key</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,)</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">author</span><span class=\"o\">.</span><span class=\"n\">natural_key</span><span class=\"p\">()</span>\n\n\n<span class=\"n\">natural_key</span><span class=\"o\">.</span><span class=\"n\">dependencies</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;example_app.person&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>この定義により、すべての <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> オブジェクトは <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> オブジェクトよりも先にシリアライズされます。また、<code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> を参照するオブジェクトは <code class=\"docutils literal notranslate\"><span class=\"pre\">Person</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> の両方がシリアライズされた後にシリアライズされます。</p>\n</section>\n</section>","rootId":"serializing-django-objects","toc":[{"title":"データのシリアライズ","anchor":"serializing-data","children":[{"title":"フィールドのサブセット","anchor":"subset-of-fields","children":[]},{"title":"継承されたモデル","anchor":"inherited-models","children":[]}]},{"title":"データのデシリアライズ","anchor":"deserializing-data","children":[]},{"title":"シリアライズフォーマット","anchor":"serialization-formats","children":[{"title":"XML","anchor":"xml","children":[]},{"title":"JSON","anchor":"serialization-formats-json","children":[{"title":"DjangoJSONEncoder","anchor":"djangojsonencoder","children":[]}]},{"title":"JSONL","anchor":"serialization-formats-jsonl","children":[]},{"title":"YAML","anchor":"yaml","children":[]}]},{"title":"ナチュラルキー","anchor":"natural-keys","children":[{"title":"ナチュラルキーのデシリアライズ","anchor":"deserialization-of-natural-keys","children":[]},{"title":"ナチュラルキーのシリアライズ","anchor":"serialization-of-natural-keys","children":[]},{"title":"ナチュラルキーと前方参照","anchor":"natural-keys-and-forward-references","children":[]},{"title":"シリアライズ中の依存関係","anchor":"dependencies-during-serialization","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/5.1/topics/"}],"prev":{"docname":"topics/performance","title":"パフォーマンスと最適化","url":"/ja/5.1/topics/performance/"},"next":{"docname":"topics/settings","title":"Djangoの設定","url":"/ja/5.1/topics/settings/"},"formats":{"html":"/ja/5.1/topics/serialization/","markdown":"/ja/5.1/topics/serialization.md","json":"/ja/5.1/topics/serialization.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/serialization.txt","official":"https://docs.djangoproject.com/ja/5.1/topics/serialization/","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"]}