{"title":"Composite primary keys","version":"6.0","locale":"zh-hans","docname":"topics/composite-primary-key","url":"/zh-hans/6.0/topics/composite-primary-key/","canonical":"https://djangodocs.dev/zh-hans/6.0/topics/composite-primary-key/","summary":"In Django, each model has a primary key. By default, this primary key consists of a single field. In most cases, a single primary key should suffice.","html":"<h1>Composite primary keys<a class=\"heading-anchor\" href=\"#composite-primary-keys\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<aside class=\"version-note version-added\" data-version=\"5.2\" role=\"note\">\n<p class=\"version-note-title\">New in Django 5.2</p></aside>\n<p>In Django, each model has a primary key. By default, this primary key consists\nof a single field.</p>\n<p>In most cases, a single primary key should suffice. In database design,\nhowever, defining a primary key consisting of multiple fields is sometimes\nnecessary.</p>\n<p>To use a composite primary key, when defining a model set the <code class=\"docutils literal notranslate\">pk</code> attribute\nto be a <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.CompositePrimaryKey\" title=\"django.db.models.CompositePrimaryKey\"><code class=\"xref py py-class docutils literal notranslate\">CompositePrimaryKey</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\">Product</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\">100</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Order</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    reference <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">,</span> primary_key<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">OrderLineItem</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    pk <span class=\"o\">=</span> models<span class=\"o\">.</span>CompositePrimaryKey<span class=\"p\">(</span><span class=\"s2\">&quot;product_id&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;order_id&quot;</span><span class=\"p\">)</span>\n    product <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Product<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    order <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Order<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    quantity <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n</code></pre></div>\n<p>This will instruct Django to create a composite primary key\n(<code class=\"docutils literal notranslate\">PRIMARY KEY (product_id, order_id)</code>) when creating the table.</p>\n<p>A composite primary key is represented by a <code class=\"docutils literal notranslate\">tuple</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>product <span class=\"o\">=</span> Product<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s2\">&quot;apple&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>order <span class=\"o\">=</span> Order<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>reference<span class=\"o\">=</span><span class=\"s2\">&quot;A755H&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>item <span class=\"o\">=</span> OrderLineItem<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>product<span class=\"o\">=</span>product<span class=\"p\">,</span> order<span class=\"o\">=</span>order<span class=\"p\">,</span> quantity<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>item<span class=\"o\">.</span>pk\n<span class=\"go\">(1, &quot;A755H&quot;)</span>\n</code></pre></div>\n<p>You can assign a <code class=\"docutils literal notranslate\">tuple</code> to the <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/instances/#django.db.models.Model.pk\" title=\"django.db.models.Model.pk\"><code class=\"xref py py-attr docutils literal notranslate\">pk</code></a> attribute.\nThis sets the associated field values:</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>item <span class=\"o\">=</span> OrderLineItem<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s2\">&quot;B142C&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>item<span class=\"o\">.</span>pk\n<span class=\"go\">(2, &quot;B142C&quot;)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>item<span class=\"o\">.</span>product_id\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>item<span class=\"o\">.</span>order_id\n<span class=\"go\">&quot;B142C&quot;</span>\n</code></pre></div>\n<p>A composite primary key can also be filtered by a <code class=\"docutils literal notranslate\">tuple</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>OrderLineItem<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s2\">&quot;A755H&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span>count<span class=\"p\">()</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p>We're still working on composite primary key support for\n<a class=\"reference internal\" href=\"#cpk-and-relations\"><span class=\"std std-ref\">relational fields</span></a>, including\n<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/contrib/contenttypes/#django.contrib.contenttypes.fields.GenericForeignKey\" title=\"django.contrib.contenttypes.fields.GenericForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">GenericForeignKey</code></a> fields, and the Django admin. Models with composite\nprimary keys cannot be registered in the Django admin at this time. You can\nexpect to see this in future releases.</p>\n<section id=\"migrating-to-a-composite-primary-key\">\n<h2>Migrating to a composite primary key<a class=\"heading-anchor\" href=\"#migrating-to-a-composite-primary-key\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django doesn't support migrating to, or from, a composite primary key after the\ntable is created. It also doesn't support adding or removing fields from the\ncomposite primary key.</p>\n<p>If you would like to migrate an existing table from a single primary key to a\ncomposite primary key, follow your database backend's instructions to do so.</p>\n<p>Once the composite primary key is in place, add the <code class=\"docutils literal notranslate\">CompositePrimaryKey</code>\nfield to your model. This allows Django to recognize and handle the composite\nprimary key appropriately.</p>\n<p>While migration operations (e.g. <code class=\"docutils literal notranslate\">AddField</code>, <code class=\"docutils literal notranslate\">AlterField</code>) on primary key\nfields are not supported, <code class=\"docutils literal notranslate\">makemigrations</code> will still detect changes.</p>\n<p>In order to avoid errors, it's recommended to apply such migrations with\n<code class=\"docutils literal notranslate\">--fake</code>.</p>\n<p>Alternatively, <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/migration-operations/#django.db.migrations.operations.SeparateDatabaseAndState\" title=\"django.db.migrations.operations.SeparateDatabaseAndState\"><code class=\"xref py py-class docutils literal notranslate\">SeparateDatabaseAndState</code></a> may be used to execute the\nbackend-specific migrations and Django-generated migrations in a single\noperation.</p>\n</section>\n<section id=\"composite-primary-keys-and-relations\">\n<span id=\"cpk-and-relations\"></span><h2>Composite primary keys and relations<a class=\"heading-anchor\" href=\"#composite-primary-keys-and-relations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#relationship-fields\"><span class=\"std std-ref\">Relationship fields</span></a>, including\n<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/contrib/contenttypes/#generic-relations\"><span class=\"std std-ref\">generic relations</span></a> do not support composite primary\nkeys.</p>\n<p>For example, given the <code class=\"docutils literal notranslate\">OrderLineItem</code> model, the following is not\nsupported:</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\">Foo</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    item <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>OrderLineItem<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n</code></pre></div>\n<p>Because <code class=\"docutils literal notranslate\">ForeignKey</code> currently cannot reference models with composite primary\nkeys.</p>\n<p>To work around this limitation, <code class=\"docutils literal notranslate\">ForeignObject</code> can be used as an\nalternative:</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\">Foo</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    item_order_id <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">20</span><span class=\"p\">)</span>\n    item_product_id <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">()</span>\n    item <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignObject<span class=\"p\">(</span>\n        OrderLineItem<span class=\"p\">,</span>\n        on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">,</span>\n        from_fields<span class=\"o\">=</span><span class=\"p\">(</span><span class=\"s2\">&quot;item_order_id&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;item_product_id&quot;</span><span class=\"p\">),</span>\n        to_fields<span class=\"o\">=</span><span class=\"p\">(</span><span class=\"s2\">&quot;order_id&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;product_id&quot;</span><span class=\"p\">),</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">ForeignObject</code> is much like <code class=\"docutils literal notranslate\">ForeignKey</code>, except that it doesn't create\nany columns (e.g. <code class=\"docutils literal notranslate\">item_id</code>), foreign key constraints or indexes in the\ndatabase, and the <code class=\"docutils literal notranslate\">on_delete</code> argument is ignored.</p>\n</section>\n<section id=\"composite-primary-keys-and-database-functions\">\n<span id=\"cpk-and-database-functions\"></span><h2>Composite primary keys and database functions<a class=\"heading-anchor\" href=\"#composite-primary-keys-and-database-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Many database functions only accept a single expression.</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</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=\"SQL code\"><code><span class=\"k\">MAX</span><span class=\"p\">(</span><span class=\"ss\">&quot;order_id&quot;</span><span class=\"p\">)</span>  <span class=\"c1\">-- OK</span>\n<span class=\"k\">MAX</span><span class=\"p\">(</span><span class=\"ss\">&quot;product_id&quot;</span><span class=\"p\">,</span> <span class=\"ss\">&quot;order_id&quot;</span><span class=\"p\">)</span>  <span class=\"c1\">-- ERROR</span>\n</code></pre></div>\n<p>In these cases, providing a composite primary key reference raises a\n<code class=\"docutils literal notranslate\">ValueError</code>, since it is composed of multiple column expressions. An\nexception is made for <code class=\"docutils literal notranslate\">Count</code>.</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code>Max<span class=\"p\">(</span><span class=\"s2\">&quot;order_id&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># OK</span>\nMax<span class=\"p\">(</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># ValueError</span>\nCount<span class=\"p\">(</span><span class=\"s2\">&quot;pk&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># OK</span>\n</code></pre></div>\n</section>\n<section id=\"composite-primary-keys-in-forms\">\n<h2>Composite primary keys in forms<a class=\"heading-anchor\" href=\"#composite-primary-keys-in-forms\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>As a composite primary key is a virtual field, a field which doesn't represent\na single database column, this field is excluded from ModelForms.</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\">OrderLineItemForm</span><span class=\"p\">(</span>forms<span class=\"o\">.</span>ModelForm<span class=\"p\">):</span>\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        model <span class=\"o\">=</span> OrderLineItem\n        fields <span class=\"o\">=</span> <span class=\"s2\">&quot;__all__&quot;</span>\n</code></pre></div>\n<p>This form does not have a form field <code class=\"docutils literal notranslate\">pk</code> for the composite primary key:</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>OrderLineItemForm<span class=\"p\">()</span>\n<span class=\"go\">&lt;OrderLineItemForm bound=False, valid=Unknown, fields=(product;order;quantity)&gt;</span>\n</code></pre></div>\n<p>Setting the primary composite field <code class=\"docutils literal notranslate\">pk</code> as a form field raises an unknown\nfield <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/exceptions/#django.core.exceptions.FieldError\" title=\"django.core.exceptions.FieldError\"><code class=\"xref py py-exc docutils literal notranslate\">FieldError</code></a>.</p>\n<aside class=\"admonition-primary-key-fields-are-read-only admonition\" role=\"note\">\n<p class=\"admonition-title\">Primary key fields are read only</p>\n<p>If you change the value of a primary key on an existing object and then\nsave it, a new object will be created alongside the old one (see\n<a class=\"reference internal\" href=\"/zh-hans/6.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\">Field.primary_key</code></a>).</p>\n<p>This is also true of composite primary keys. Hence, you may want to set\n<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/fields/#django.db.models.Field.editable\" title=\"django.db.models.Field.editable\"><code class=\"xref py py-attr docutils literal notranslate\">Field.editable</code></a> to <code class=\"docutils literal notranslate\">False</code> on all primary key fields to exclude\nthem from ModelForms.</p>\n</aside>\n</section>\n<section id=\"composite-primary-keys-in-model-validation\">\n<h2>Composite primary keys in model validation<a class=\"heading-anchor\" href=\"#composite-primary-keys-in-model-validation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Since <code class=\"docutils literal notranslate\">pk</code> is only a virtual field, including <code class=\"docutils literal notranslate\">pk</code> as a field name in the\n<code class=\"docutils literal notranslate\">exclude</code> argument of <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/instances/#django.db.models.Model.clean_fields\" title=\"django.db.models.Model.clean_fields\"><code class=\"xref py py-meth docutils literal notranslate\">Model.clean_fields()</code></a> has no effect. To exclude\nthe composite primary key fields from\n<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/instances/#validating-objects\"><span class=\"std std-ref\">model validation</span></a>, specify each field individually.\n<a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/instances/#django.db.models.Model.validate_unique\" title=\"django.db.models.Model.validate_unique\"><code class=\"xref py py-meth docutils literal notranslate\">Model.validate_unique()</code></a> can still be called with <code class=\"docutils literal notranslate\">exclude={&quot;pk&quot;}</code> to\nskip uniqueness checks.</p>\n</section>\n<section id=\"building-composite-primary-key-ready-applications\">\n<h2>Building composite primary key ready applications<a class=\"heading-anchor\" href=\"#building-composite-primary-key-ready-applications\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Prior to the introduction of composite primary keys, the single field composing\nthe primary key of a model could be retrieved by introspecting the\n<a class=\"reference internal\" href=\"/zh-hans/6.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> attribute of its\nfields:</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>pk_field <span class=\"o\">=</span> <span class=\"kc\">None</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> field <span class=\"ow\">in</span> Product<span class=\"o\">.</span>_meta<span class=\"o\">.</span>get_fields<span class=\"p\">():</span>\n<span class=\"gp\">... </span>    <span class=\"k\">if</span> field<span class=\"o\">.</span>primary_key<span class=\"p\">:</span>\n<span class=\"gp\">... </span>        pk_field <span class=\"o\">=</span> field\n<span class=\"gp\">... </span>        <span class=\"k\">break</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>pk_field\n<span class=\"go\">&lt;django.db.models.fields.AutoField: id&gt;</span>\n</code></pre></div>\n<p>Now that a primary key can be composed of multiple fields the\n<a class=\"reference internal\" href=\"/zh-hans/6.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> attribute can no\nlonger be relied upon to identify members of the primary key as it will be set\nto <code class=\"docutils literal notranslate\">False</code> to maintain the invariant that at most one field per model will\nhave this attribute set to <code class=\"docutils literal notranslate\">True</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>pk_fields <span class=\"o\">=</span> <span class=\"p\">[]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> field <span class=\"ow\">in</span> OrderLineItem<span class=\"o\">.</span>_meta<span class=\"o\">.</span>get_fields<span class=\"p\">():</span>\n<span class=\"gp\">... </span>    <span class=\"k\">if</span> field<span class=\"o\">.</span>primary_key<span class=\"p\">:</span>\n<span class=\"gp\">... </span>        pk_fields<span class=\"o\">.</span>append<span class=\"p\">(</span>field<span class=\"p\">)</span>\n<span class=\"gp\">...</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>pk_fields\n<span class=\"go\">[]</span>\n</code></pre></div>\n<p>In order to build application code that properly handles composite primary\nkeys the <a class=\"reference internal\" href=\"/zh-hans/6.0/ref/models/meta/#django.db.models.options.Options.pk_fields\" title=\"django.db.models.options.Options.pk_fields\"><code class=\"xref py py-attr docutils literal notranslate\">_meta.pk_fields</code></a>\nattribute should be used instead:</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>Product<span class=\"o\">.</span>_meta<span class=\"o\">.</span>pk_fields\n<span class=\"go\">[&lt;django.db.models.fields.AutoField: id&gt;]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>OrderLineItem<span class=\"o\">.</span>_meta<span class=\"o\">.</span>pk_fields\n<span class=\"go\">[</span>\n<span class=\"go\">    &lt;django.db.models.fields.ForeignKey: product&gt;,</span>\n<span class=\"go\">    &lt;django.db.models.fields.ForeignKey: order&gt;</span>\n<span class=\"go\">]</span>\n</code></pre></div>\n</section>","rootId":"composite-primary-keys","toc":[{"title":"Migrating to a composite primary key","anchor":"migrating-to-a-composite-primary-key","children":[]},{"title":"Composite primary keys and relations","anchor":"composite-primary-keys-and-relations","children":[]},{"title":"Composite primary keys and database functions","anchor":"composite-primary-keys-and-database-functions","children":[]},{"title":"Composite primary keys in forms","anchor":"composite-primary-keys-in-forms","children":[]},{"title":"Composite primary keys in model validation","anchor":"composite-primary-keys-in-model-validation","children":[]},{"title":"Building composite primary key ready applications","anchor":"building-composite-primary-key-ready-applications","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/6.0/topics/"}],"prev":{"docname":"topics/conditional-view-processing","title":"条件视图处理","url":"/zh-hans/6.0/topics/conditional-view-processing/"},"next":{"docname":"topics/signing","title":"加密签名","url":"/zh-hans/6.0/topics/signing/"},"formats":{"html":"/zh-hans/6.0/topics/composite-primary-key/","markdown":"/zh-hans/6.0/topics/composite-primary-key.md","json":"/zh-hans/6.0/topics/composite-primary-key.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/topics/composite-primary-key.txt","official":"https://docs.djangoproject.com/zh-hans/6.0/topics/composite-primary-key/","inVersions":["6.1","6.0","5.2"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}