Получение данных из отношения "один к одному"
Во-первых, получите сотрудника с именем John Doe:
e = Employee.objects.filter(first_name='John',last_name='Doe').first()
Django выполняет SELECT оператор, который получает строку с first_name 'John' и last_name 'Doe'.
У компании hr_employee может быть несколько сотрудников с одинаковыми именем и фамилией. Следовательно, filter() возвращает QuerySet. Чтобы получить первую строку в QuerySet, мы используем first() метод. Метод first() возвращает один экземпляр класса Employee.
Обратите внимание, что запрос не получает контактные данные из hr_contact таблицы. Он получает данные только из hr_employee таблицы.
При доступе к contact атрибуту сотрудника:
e.contact
Django выполняет второй SELECT оператор для получения данных из hr_contact таблицы:
Следующее получает контакт с идентификатором 1:
c = Contact.objects.get(id=1)
При привязке контакта к сотруднику вы можете получить доступ employee к contact объекту:
c.employee
Django выполняет SELECT оператор для получения данных из hr_employee таблицы:
Обратите внимание, что Contact класс не имеет employee атрибута. Однако вы можете получить доступ, employee если контакт связан с ним.
Давайте создадим еще один контакт, который не связан ни с одним сотрудником:
c = Contact(phone='+79121111111',address='Sankt-Peterburg, Lenin Street, 82')
c.save()
Django выполнит следующий INSERT оператор:
Если вы найдете контакт, который не связан ни с одним сотрудником, и получите доступ к сотруднику, вы получите исключение RelatedObjectDoesNotExist.
Выбор связанных объектов
Сначала создайте нового сотрудника:
e = Employee(first_name='Jane',last_name='Doe')
e.save()
Во-вторых, получить всех сотрудников:
>>> Employee.objects.all()
Django возвращает двух сотрудников
Если вам нужно отобразить всех сотрудников, а также их контакты на одной странице, то у вас проблема с запросом N+1:
- Во-первых, вам нужен один запрос, чтобы получить всех сотрудников (
Nсотрудников). - Во-вторых, вам нужно
Nзапросов, чтобы выбрать связанный контакт каждого сотрудника.
В случае с нашим простым примером это не проблема, но в больших базах данных с большим количеством связей нагрузка на базу данных может быть непомерно высокой. Чтобы избежать этого, вы можете запросить всех сотрудников и контакты с помощью одного запроса, используя select_related() метод:
Employee.objects.select_related('contact').all()
В этом случае Django выполняет следующий LEFT JOIN оператор:
Django использует LEFT JOIN, чтобы вернуть всех сотрудников из hr_employee таблицы и контакты, связанные с выбранными сотрудниками:
<QuerySet [<Employee: John Doe>, <Employee: Jane Doe>]>
В заключение, отношения «один к одному» — полезный инструмент для моделирования сложных отношений в Django. Используя OneToOneField, вы можете легко определить уникальную связь между двумя моделями.