{"id":6173,"date":"2022-12-09T07:06:42","date_gmt":"2022-12-09T07:06:42","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=6173"},"modified":"2023-01-18T03:10:45","modified_gmt":"2023-01-18T03:10:45","slug":"django-one-to-one","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/django-tutorial\/django-one-to-one\/","title":{"rendered":"Django One-To-One Relationship"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn about Django&#8217;s one-to-one relationship and how it works under the hood.<\/p>\n\n\n\n<p class=\"note\">This tutorial begins where&nbsp;the&nbsp;<a href=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-orm\/\">Django ORM tutorial<\/a>&nbsp;left off.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-django-one-to-one-relationship'>Introduction to the Django One-To-One relationship <a href=\"#introduction-to-the-django-one-to-one-relationship\" class=\"anchor\" id=\"introduction-to-the-django-one-to-one-relationship\" title=\"Anchor for Introduction to the Django One-To-One relationship\">#<\/a><\/h2>\n\n\n\n<p>The one-to-one relationship defines a link between two tables, where each row in a table appears once in another table.<\/p>\n\n\n\n<p>For example, each employee has a contact and each contact belongs to one employee. So the relationship between employees and contacts is a one-to-one relationship.<\/p>\n\n\n\n<p>To create a one-to-one relationship, you use the <code>OneToOneField<\/code> class:<\/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\">OneToOneField(to, on_delete, parent_link=<span class=\"hljs-literal\">False<\/span>, **options)<\/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>In this syntax:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>to<\/code> parameter defines the model name. <\/li>\n\n\n\n<li><code>on_delete<\/code> specifies an action on the contact when the employee is deleted.<\/li>\n<\/ul>\n\n\n\n<p>The following example uses a <code>OneToOneField<\/code> class to define a one-to-one relationship between <code>Contact<\/code> and <code>Employee<\/code> models in the <code>models.py<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">from<\/span> django.db <span class=\"hljs-keyword\">import<\/span> models\n\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Contact<\/span><span class=\"hljs-params\">(models.Model)<\/span>:<\/span>\n    phone = models.CharField(max_length=<span class=\"hljs-number\">50<\/span>, unique=<span class=\"hljs-literal\">True<\/span>)\n    address = models.CharField(max_length=<span class=\"hljs-number\">50<\/span>)\n\n    <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 class=\"hljs-keyword\">return<\/span> self.phone\n\n\n<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    first_name = models.CharField(max_length=<span class=\"hljs-number\">100<\/span>)\n    last_name = models.CharField(max_length=<span class=\"hljs-number\">100<\/span>)\n    contact = models.OneToOneField(Contact, on_delete=models.CASCADE)\n\n    <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 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><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><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>The <code>Employee<\/code> class has the <code>contact<\/code> attribute that references an instance of the <code>OneToOneField<\/code> class.<\/p>\n\n\n\n<p>In the <code>OneToOneField<\/code>, we specify the <code>Contact<\/code> model and the <code>on_delete<\/code> option that defines the behavior when an employee object is deleted.<\/p>\n\n\n\n<p>The <code>on_delete<\/code>=<code>models.CASCADE<\/code> option means if an <code>Employee<\/code> object is deleted, the <code>Contact<\/code> object associated with the <code>Employee<\/code> will also be deleted automatically.<\/p>\n\n\n\n<p class=\"note\">Note that Django creates a <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-foreign-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">foreign key constraint<\/a> in the database without an <code>ON DELETE CASCADE<\/code> option. Instead, Django handles the deletion manually in the application. Note that this internal implementation may change in the future.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='migrating-models-to-the-database'>Migrating models to the database <a href=\"#migrating-models-to-the-database\" class=\"anchor\" id=\"migrating-models-to-the-database\" title=\"Anchor for Migrating models to the database\">#<\/a><\/h2>\n\n\n\n<p>First, make migrations using the <code>makemigrations<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python manage.py makemigrations<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><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<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Migrations <span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-string\">'hr'<\/span>:\n  hr\\migrations\\<span class=\"hljs-number\">0002<\/span>_contact_employee_contact.py\n    - Create model Contact\n    - Add field contact to employee<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><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, apply the migrations to the database using the <code>migrate<\/code> command:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">python manage.py migrate<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><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<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Operations to perform:\n  Apply all migrations: admin, auth, contenttypes, hr, sessions\nRunning migrations:\n  Applying hr<span class=\"hljs-number\">.0002<\/span>_contact_employee_contact... OK<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><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>Behind the scenes, Django creates two tables <code>hr_contact<\/code> and <code>hr_employee<\/code> in the database:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"504\" height=\"182\" src=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-one-to-one-database-tables.png\" alt=\"\" class=\"wp-image-6175\" srcset=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-one-to-one-database-tables.png 504w, https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/Django-one-to-one-database-tables-300x108.png 300w\" sizes=\"auto, (max-width: 504px) 100vw, 504px\" \/><\/figure>\n\n\n\n<p>The <code>hr_employee<\/code> table has the <code>contact_id<\/code> column which is a <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-foreign-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">foreign key<\/a> that links to the id (<a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-primary-key\/\" target=\"_blank\" rel=\"noreferrer noopener\">primary key<\/a>) of the <code>hr_contact<\/code> table.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='associating-a-contact-with-an-employee'>Associating a contact with an employee <a href=\"#associating-a-contact-with-an-employee\" class=\"anchor\" id=\"associating-a-contact-with-an-employee\" title=\"Anchor for Associating a contact with an employee\">#<\/a><\/h2>\n\n\n\n<p>To interact with the <code>Employee<\/code> and <code>Contact<\/code> models, you run the <code>shell_plus<\/code> command with the <code>--print-sql<\/code> option:<\/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\">python manage.py shell_plus --<span class=\"hljs-keyword\">print<\/span>-sql<\/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>The <code>--print-sql<\/code> option outputs the SQL command that Django executes.<\/p>\n\n\n\n<p>First, create a new <code>Employee<\/code> object and save it to the database:<\/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(first_name=<span class=\"hljs-string\">'John'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()<\/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<p>Django executes the following SQL  command:<\/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\">INSERT INTO <span class=\"hljs-string\">\"hr_employee\"<\/span> (<span class=\"hljs-string\">\"first_name\"<\/span>, <span class=\"hljs-string\">\"last_name\"<\/span>, <span class=\"hljs-string\">\"contact_id\"<\/span>)\nVALUES (<span class=\"hljs-string\">'John'<\/span>, <span class=\"hljs-string\">'Doe'<\/span>, NULL) \nRETURNING <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span><\/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, create and save a new contact into the database:<\/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>c = Contact(phone=<span class=\"hljs-string\">'40812345678'<\/span>, address=<span class=\"hljs-string\">'101 N 1st Street, San Jose, CA'<\/span>)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c.save()<\/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>Django also executes the following <code><a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-insert\/\" target=\"_blank\" rel=\"noreferrer noopener\">INSERT<\/a><\/code> command:<\/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\">INSERT INTO <span class=\"hljs-string\">\"hr_contact\"<\/span> (<span class=\"hljs-string\">\"phone\"<\/span>, <span class=\"hljs-string\">\"address\"<\/span>)\nVALUES (<span class=\"hljs-string\">'40812345678'<\/span>, <span class=\"hljs-string\">'101 N 1st Street, San Jose, CA'<\/span>) \nRETURNING <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span><\/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>Third, associate a contact with an employee:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" 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.contact = c\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><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>Django updates the value of the <code>contact_id<\/code> column in the <code>hr_employee<\/code> table to the value of the <code>id<\/code> column in the <code>hr_contact<\/code> table.<\/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\">UPDATE <span class=\"hljs-string\">\"hr_employee\"<\/span>\n   SET <span class=\"hljs-string\">\"first_name\"<\/span> = <span class=\"hljs-string\">'John'<\/span>,\n       <span class=\"hljs-string\">\"last_name\"<\/span> = <span class=\"hljs-string\">'Doe'<\/span>,\n       <span class=\"hljs-string\">\"contact_id\"<\/span> = <span class=\"hljs-number\">1<\/span>\n WHERE <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span> = <span class=\"hljs-number\">3<\/span><\/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<h2 class=\"wp-block-heading\" id='getting-data-from-a-one-to-one-relationship'>Getting data from a one-to-one relationship <a href=\"#getting-data-from-a-one-to-one-relationship\" class=\"anchor\" id=\"getting-data-from-a-one-to-one-relationship\" title=\"Anchor for Getting data from a one-to-one relationship\">#<\/a><\/h2>\n\n\n\n<p>First, get the employee with the name <code>John Doe<\/code>:<\/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>e = Employee.objects.filter(first_name=<span class=\"hljs-string\">'John'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>).first()\n&lt;Employee: John Doe&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>Django executes the <code>SELECT<\/code> statement that gets the row with the <code>first_name<\/code> <code>'John'<\/code> and <code>last_name<\/code> <code>'Doe'<\/code>.  <\/p>\n\n\n\n<p>The <code>hr_employee<\/code> may have multiple employees with the same first name and last name. Therefore, the <code>filter()<\/code> returns a <code>QuerySet<\/code>. <\/p>\n\n\n\n<p>To get the first row in the <code>QuerySet<\/code>, we use the <code>first()<\/code> method. The <code>first()<\/code> method returns a single instance of the <code>Employee<\/code> class.<\/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\">SELECT <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"first_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"last_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"contact_id\"<\/span>\n  FROM <span class=\"hljs-string\">\"hr_employee\"<\/span>\n WHERE (<span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"first_name\"<\/span> = <span class=\"hljs-string\">'John'<\/span> AND <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"last_name\"<\/span> = <span class=\"hljs-string\">'Doe'<\/span>)\n ORDER BY <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span> ASC\n LIMIT <span class=\"hljs-number\">1<\/span><\/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>Note that the query doesn&#8217;t get the contact data from the <code>hr_contact<\/code> table. It only gets data from the <code>hr_employee<\/code> table.<\/p>\n\n\n\n<p>When you access the <code>contact<\/code> attribute of the employee:<\/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>e.contact<\/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<p>&#8230; Django executes the second <code>SELECT<\/code> statement to get data from the <code>hr_contact<\/code> table:<\/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\">SELECT <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"phone\"<\/span>,\n       <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"address\"<\/span>\n  FROM <span class=\"hljs-string\">\"hr_contact\"<\/span>\n WHERE <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span> = <span class=\"hljs-number\">1<\/span>\n LIMIT <span class=\"hljs-number\">21<\/span>\n&lt;Contact: <span class=\"hljs-number\">40812345678<\/span>&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>The following gets the contact with id 1:<\/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>c = Contact.objects.get(id=<span class=\"hljs-number\">1<\/span>)<\/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>When associating a contact with an employee, you can access the <code>employee<\/code> from the <code>contact<\/code> object:<\/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>c.employee\n&lt;Employee: John Doe&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>Django executes a <code>SELECT<\/code> statement to get data from the <code>hr_employee<\/code> table:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">SELECT <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"first_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"last_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"contact_id\"<\/span>\n  FROM <span class=\"hljs-string\">\"hr_employee\"<\/span>\n WHERE <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"contact_id\"<\/span> = <span class=\"hljs-number\">1<\/span>\n LIMIT <span class=\"hljs-number\">21<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><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>Note that the <code>Contact<\/code> class doesn&#8217;t have the <code>employee<\/code> attribute. However, you can access the <code>employee<\/code> if the contact is associated with one.<\/p>\n\n\n\n<p>Let&#8217;s create another contact that doesn&#8217;t associate with any employee:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c = Contact(phone=<span class=\"hljs-string\">'4081111111'<\/span>,address=<span class=\"hljs-string\">'202 N 1st Street, San Jose, CA'<\/span>)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>c.save()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><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>Django will execute the following <code>INSERT<\/code> statement:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">INSERT INTO <span class=\"hljs-string\">\"hr_contact\"<\/span> (<span class=\"hljs-string\">\"phone\"<\/span>, <span class=\"hljs-string\">\"address\"<\/span>)\nVALUES (<span class=\"hljs-string\">'4081111111'<\/span>, <span class=\"hljs-string\">'202 N 1st Street, San Jose, CA'<\/span>) \nRETURNING <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><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>If you find a contact that doesn&#8217;t associate with any employee and access the employee, you&#8217;ll get a <code>RelatedObjectDoesNotExist<\/code> exception.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='selecting-related-objects'>Selecting related objects <a href=\"#selecting-related-objects\" class=\"anchor\" id=\"selecting-related-objects\" title=\"Anchor for Selecting related objects\">#<\/a><\/h2>\n\n\n\n<p>First, create a new employee:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" 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(first_name=<span class=\"hljs-string\">'Jane'<\/span>,last_name=<span class=\"hljs-string\">'Doe'<\/span>)\n<span class=\"hljs-meta\">&gt;&gt;&gt; <\/span>e.save()\nINSERT INTO <span class=\"hljs-string\">\"hr_employee\"<\/span> (<span class=\"hljs-string\">\"first_name\"<\/span>, <span class=\"hljs-string\">\"last_name\"<\/span>, <span class=\"hljs-string\">\"contact_id\"<\/span>)\nVALUES (<span class=\"hljs-string\">'Jane'<\/span>, <span class=\"hljs-string\">'Doe'<\/span>, NULL) RETURNING <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>\nExecution time: <span class=\"hljs-number\">0.003079<\/span>s &#91;Database: default]<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><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, get all employees:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" 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.all()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><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>Django returns two employees:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">&lt;QuerySet &#91;&lt;Employee: John Doe&gt;, &lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><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>If you have to display all employees as well as their contacts on the same page, then you have the N+1 query problem:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, you need one query to get all employees (N employees).<\/li>\n\n\n\n<li>Second, you need N queries to select the related contact of each employee.<\/li>\n<\/ul>\n\n\n\n<p>To avoid this, you can query all employees and contacts using a single query by using the <code>select_related()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" 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.select_related(<span class=\"hljs-string\">'contact'<\/span>).all()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><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>In this case, Django executes the following <a href=\"https:\/\/www.postgresqltutorial.com\/postgresql-tutorial\/postgresql-left-join\/\" target=\"_blank\" rel=\"noreferrer noopener\"><code>LEFT<\/code> <code>JOIN<\/code><\/a> statement:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">SELECT <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"first_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"last_name\"<\/span>,\n       <span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"contact_id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>,\n       <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"phone\"<\/span>,\n       <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"address\"<\/span>\n  FROM <span class=\"hljs-string\">\"hr_employee\"<\/span>\n  LEFT OUTER JOIN <span class=\"hljs-string\">\"hr_contact\"<\/span>\n    ON (<span class=\"hljs-string\">\"hr_employee\"<\/span>.<span class=\"hljs-string\">\"contact_id\"<\/span> = <span class=\"hljs-string\">\"hr_contact\"<\/span>.<span class=\"hljs-string\">\"id\"<\/span>)\n LIMIT <span class=\"hljs-number\">21<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><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>Django uses <code>LEFT<\/code> <code>JOIN<\/code> that returns all employees from the <code>hr_employee<\/code> table and contacts associated with the selected employees:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">&lt;QuerySet &#91;&lt;Employee: John Doe&gt;, &lt;Employee: Jane Doe&gt;]&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><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 class=\"note\"><a href=\"https:\/\/www.pythontutorial.net\/wp-content\/uploads\/2022\/12\/django_orm_2.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Download the project source code here<\/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>Use <code>OneToOneField<\/code> class to establish a one-to-one relationship.<\/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=\"6173\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-one-to-one\/\"\n\t\t\t\tdata-post-title=\"Django One-To-One 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=\"6173\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/django-tutorial\/django-one-to-one\/\"\n\t\t\t\tdata-post-title=\"Django One-To-One 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 about Django one-to-one relationship and how it works under the hood.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":5531,"menu_order":23,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6173","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6173","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=6173"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6173\/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=6173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}