{"id":6232,"date":"2022-12-25T09:00:56","date_gmt":"2022-12-25T09:00:56","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=6232"},"modified":"2023-01-18T03:22:19","modified_gmt":"2023-01-18T03:22:19","slug":"django-many-to-many","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/django-tutorial\/django-many-to-many\/","title":{"rendered":"Django Many-to-Many Relationship"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn how to use <code>ManyToManyField<\/code> to model a Many-to-Many relationship in Django.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-django-many-to-many-relationship'>Introduction to the Django Many-to-Many relationship <a href=\"#introduction-to-the-django-many-to-many-relationship\" class=\"anchor\" id=\"introduction-to-the-django-many-to-many-relationship\" title=\"Anchor for Introduction to the Django Many-to-Many relationship\">#<\/a><\/h2>\n\n\n\n<p>In a many-to-many relationship, multiple rows in a table are associated with multiple rows in another table.<\/p>\n\n\n\n<p>For example, an employee may have multiple compensation programs and a compensation program may belong to multiple employees.<\/p>\n\n\n\n<p>Therefore, multiple rows in the employee table are associated with multiple rows in the compensation table. Hence, the relationship between employees and compensation programs is a many-to-many relationship.<\/p>\n\n\n\n<p>Typically, relational databases do not implement a direct many-to-many relationship between two tables. Instead, it uses a third table, the join table, to establish two <a href=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-one-to-many\/\">one-to-many relationships<\/a> between the two tables and the join table.<\/p>\n\n\n\n<p>The following diagram illustrates the many-to-many relationships in the database between the hr_employee and hr_compensation tables:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"228\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example.png\" alt=\"\" class=\"wp-image-6235\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example.png 933w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example-300x73.png 300w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example-768x188.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<p>The <code>hr_employee_compensations<\/code> table is a join table. It has two <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-foreign-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">foreign keys<\/a> <code>employee_id<\/code> and <code>compensation_id<\/code>.<\/p>\n\n\n\n<p>The <code>employee_id<\/code> foreign key references the <code>id<\/code> of the <code>hr_employee<\/code> table and the <code>compensation_id<\/code> foreign key references the <code>id<\/code> in the <code>hr_compensation<\/code> table.<\/p>\n\n\n\n<p>Typically, you don&#8217;t need the <code>id<\/code> column in the <code>hr_employee_compensations<\/code> table as a <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-primary-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">primary key<\/a> and use both <code>employee_id<\/code> and <code>compensation_id<\/code> as a composite primary key. However, Django always creates the <code>id<\/code> column as a primary key for the join table. <\/p>\n\n\n\n<p>Also, Django creates a <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-unique-constraint\/\" target=\"_blank\" rel=\"noreferrer noopener\">unique constraint<\/a> that includes the <code>employee_id<\/code> and <code>compensation_id<\/code> columns. In other words, there will be no duplicate pairs of <code>employee_id<\/code> and <code>compensation_id<\/code> values in the <code>hr_employee_compensations<\/code> table.<\/p>\n\n\n\n<p>To create a many-to-many relationship in Django, you use the <code>ManyToManyField<\/code>. For example, the following uses the <code>ManyToManyField<\/code> to create a many-to-many relationship between <code>Employee<\/code> and <code>Compensation<\/code> models:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python shcb-code-table\"><span class='shcb-loc'><span><span class=\"hljs-comment\"># ...<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Compensation<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    name = models.CharField(max_length=<span class=\"hljs-number\">255<\/span>)\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">return<\/span> self.name\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Employee<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    first_name = models.CharField(max_length=<span class=\"hljs-number\">100<\/span>)\n<\/span><\/span><span class='shcb-loc'><span>    last_name = models.CharField(max_length=<span class=\"hljs-number\">100<\/span>)\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    contact = models.OneToOneField(\n<\/span><\/span><span class='shcb-loc'><span>        Contact,\n<\/span><\/span><span class='shcb-loc'><span>        on_delete=models.CASCADE,\n<\/span><\/span><span class='shcb-loc'><span>        null=<span class=\"hljs-literal\">True<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    )\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    department = models.ForeignKey(\n<\/span><\/span><span class='shcb-loc'><span>        Department,\n<\/span><\/span><span class='shcb-loc'><span>        on_delete=models.CASCADE\n<\/span><\/span><span class='shcb-loc'><span>    )\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><mark class='shcb-loc'><span>    compensations = models.ManyToManyField(Compensation)\n<\/span><\/mark><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__str__<\/span><span class=\"hljs-params\">(self)<\/span>:<\/span>\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">f'<span class=\"hljs-subst\">{self.first_name}<\/span> <span class=\"hljs-subst\">{self.last_name}<\/span>'<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define a new <code>Compensation<\/code> model class that extends the <code>models.Model<\/code> class.<\/p>\n\n\n\n<p>Second, add the <code>compensations<\/code> field to the <code>Employee<\/code> class. The <code>compensations<\/code> field uses the <code>ManyToManyField<\/code> to establish the many-to-many relationship between the <code>Employee<\/code> and <code>Compensation<\/code> classes.<\/p>\n\n\n\n<p>To propagate the changes of the models to the database, you run the <code>makemigrations<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">python<\/span> <span class=\"hljs-selector-tag\">manage<\/span><span class=\"hljs-selector-class\">.py<\/span> <span class=\"hljs-selector-tag\">makemigrations<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>It&#8217;ll output something like this:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Migrations for 'hr':\n  hr\\migrations\\0004_compensation_employee_compensations.py\n    - Create model Compensation\n    - Add field compensations to employee<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>And execute the <code>migrate<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">python manage.py migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\">Operations to perform:\n  Apply all migrations: admin, auth, contenttypes, hr, sessions\nRunning migrations:\n  Applying hr.0004_compensation_employee_compensations... OK  <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Django created two new tables <code>hr_compensation<\/code> and a join table <code>hr_employee_compensations<\/code> as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"228\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example.png\" alt=\"\" class=\"wp-image-6235\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example.png 933w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example-300x73.png 300w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-many-to-many-example-768x188.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id='creating-data'>Creating data <a href=\"#creating-data\" class=\"anchor\" id=\"creating-data\" title=\"Anchor for Creating data\">#<\/a><\/h2>\n\n\n\n<p>First, run the <code>shell_plus<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">python<\/span> <span class=\"hljs-selector-tag\">manage<\/span><span class=\"hljs-selector-class\">.py<\/span> <span class=\"hljs-selector-tag\">shell_plus<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, create three compensation programs including <code>Stock<\/code>, <code>Bonuses<\/code>, and <code>Profit Sharing<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c1 = Compensation(name=<span class=\"hljs-string\">'Stock'<\/span>)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c1.save()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c2 = Compensation(name=<span class=\"hljs-string\">'Bonuses'<\/span>) \n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c2.save()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c3 = Compensation(name=<span class=\"hljs-string\">'Profit Sharing'<\/span>)  \n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c3.save()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>Compensation.objects.all()\n&lt;QuerySet &#91;&lt;Compensation: Stock&gt;, &lt;Compensation: Bonuses&gt;, &lt;Compensation: Profit Sharing&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, get the employee with the first name <code>John<\/code> and last name <code>Doe<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e = Employee.objects.filter(first_name=<span class=\"hljs-string\">'John'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>).first()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e\n&lt;Employee: John Doe&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='adding-compensations-to-employees'>Adding compensations to employees <a href=\"#adding-compensations-to-employees\" class=\"anchor\" id=\"adding-compensations-to-employees\" title=\"Anchor for Adding compensations to employees\">#<\/a><\/h2>\n\n\n\n<p>First, enroll <code>John Doe<\/code> in the <code>stock<\/code> (<code>c1<\/code>) and <code>bonuses <\/code>(<code>c2<\/code>) compensation programs using the <code>add()<\/code> method of the <code>compensations<\/code> attribute and the <code>save()<\/code> method of the <code>Employee<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.add(c1)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.add(c2) \n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, access all <code>compensations<\/code> program of <code>John Doe<\/code> using the <code>all()<\/code> method of the <code>compensations<\/code> attribute:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.all()\n&lt;QuerySet &#91;&lt;Compensation: Stock&gt;, &lt;Compensation: Bonuses&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>As clearly shown in the output, <code>John Doe<\/code> has two compensation programs.<\/p>\n\n\n\n<p>Third, enroll <code>Jane Doe<\/code> in three compensation programs including stock, bonuses, and profit sharing:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e = Employee.objects.filter(first_name=<span class=\"hljs-string\">'Jane'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>).first()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e \n&lt;Employee: Jane Doe&gt;\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.add(c1)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.add(c2) \n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.add(c3) \n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.all()\n&lt;QuerySet &#91;&lt;Compensation: Stock&gt;, &lt;Compensation: Bonuses&gt;, &lt;Compensation: Profit Sharing&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Internally, Django inserted the ids of employees and compensations into the join table:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"plaintext\" data-shcb-language-slug=\"plaintext\"><span><code class=\"hljs language-plaintext\"> id | employee_id | compensation_id\n----+-------------+-----------------\n  1 |           5 |               1\n  2 |           5 |               2\n  3 |           6 |               1\n  4 |           6 |               2\n  5 |           6 |               3\n(5 rows)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">plaintext<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">plaintext<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fourth, find all employees who were enrolled in the stock compensation plan using the <code>employee_set<\/code> attribute of the <code>Compensation<\/code> object:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c1\n&lt;Compensation: Stock&gt;\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c1.employee_set.all()\n&lt;QuerySet &#91;&lt;Employee: John Doe&gt;, &lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>It returned two employees as expected.<\/p>\n\n\n\n<p>Fifth, you can use the <code>employee_set<\/code> attribute to find all employees who have the profit-sharing compensation program:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c3                   \n&lt;Compensation: Profit Sharing&gt;\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c3.employee_set.all()\n&lt;QuerySet &#91;&lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>It returned one employee.<\/p>\n\n\n\n<p>Django allows you to query across the relationship. For example, you can find all employees who have the  compensation with id 1:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>Employee.objects.filter(compensations__id=<span class=\"hljs-number\">1<\/span>) \n&lt;QuerySet &#91;&lt;Employee: John Doe&gt;, &lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Or with the name <code>\"Profit Sharing\"<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>Employee.objects.filter(compensations__name=<span class=\"hljs-string\">\"Profit Sharing\"<\/span>) \n&lt;QuerySet &#91;&lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='removing-compensations-from-employees'>Removing compensations from employees <a href=\"#removing-compensations-from-employees\" class=\"anchor\" id=\"removing-compensations-from-employees\" title=\"Anchor for Removing compensations from employees\">#<\/a><\/h2>\n\n\n\n<p>To remove a compensation program from an employee, you use the <code>remove()<\/code> method of the <code>compensations<\/code> attribute of the <code>Employee<\/code> object. For example:<\/p>\n\n\n\n<p>First, get the employee whose name is <code>Jane Doe<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e = Employee.objects.filter(first_name=<span class=\"hljs-string\">'Jane'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>).first()\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e                                                                     \n&lt;Employee: Jane Doe&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, remove the <code>profit sharing<\/code> compensation (<code>c3<\/code>) from <code>Jane Doe<\/code> and save the changes to the database:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.remove(c3)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, get all the compensation programs of <code>Jane Doe<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.compensations.all()\n&lt;QuerySet &#91;&lt;Compensation: Stock&gt;, &lt;Compensation: Bonuses&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now, <code>Jane Doe<\/code> has two compensation programs left.<\/p>\n\n\n\n<p class=\"note\"><a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django_orm_4.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the Django many-to-many relationship source code<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In a many-to-many relationship, multiple rows in a table are associated with multiple rows in another table.<\/li>\n\n\n\n<li>Relation databases use a join table to establish a many-to-many relationship between two tables.<\/li>\n\n\n\n<li>Use <code>ManyToManyField<\/code> to model a many-to-many relationship between models in Django.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"6232\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-many-to-many\/\"\n\t\t\t\tdata-post-title=\"Django Many-to-Many Relationship\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"6232\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-many-to-many\/\"\n\t\t\t\tdata-post-title=\"Django Many-to-Many Relationship\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to use ManyToManyField to model a Django Many-to-Many relationship.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":5531,"menu_order":25,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6232","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6232","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=6232"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6232\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/5531"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=6232"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}