Как установить связь между полями модели внутри неё?

Как я могу получить атрибут "head" из "members" в модели "Vendor"? Какие методы можно использовать для этого?
  • 19 января 2024 г. 9:39
Ответы на вопрос 2
Если вы работаете с объектно-ориентированными языками программирования или фреймворками, такими как Django для Python, то связывание полей модели может выполняться с помощью внешних ключей (`ForeignKey`), отношения один ко многим (`OneToMany`), многие ко многим (`ManyToMany`) и так далее.

Допустим, у вас есть модель `Vendor`, которая имеет поле `head` и набор связанных `members`. В модели Django это может выглядеть примерно так:

```python
from django.db import models

class Vendor(models.Model):
    # предположим, что head это ForeignKey на модель Person
    head = models.ForeignKey('Person', on_delete=models.CASCADE, related_name='head_of_vendor')
    # другие поля...

class Person(models.Model):
    name = models.CharField(max_length=100)
    # другие поля...
    # members установить в Vendor как обратное отношение через related_name
    # для этого не надо дополнительных полей в модели Person

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
    # другие поля...
```

Теперь, если у вас есть объект `member`, который представляет запись в классе `Person`, и вы хотите получить главу (`head`) связанного с ним `Vendor`, то код может выглядеть примерно так (предполагается, что `member` принадлежит какому-то `Vendor` через модель `Membership`):

```python
# Получаем все участия человека в вендорах
memberships = Membership.objects.filter(person=member)

# Теперь мы можем перебрать их и получить глав объектов Vendor
for membership in memberships:
    head_of_vendor = membership.vendor.head
    # Теперь у вас есть объект head, который является главой Vendor, к которому принадлежит member
```

В этом примере, для каждой членской записи, мы получаем связанную модель `Vendor` через `membership.vendor` и затем обращаемся к атрибуту `head` этой модели, чтобы получить главу.

Обратите внимание, что `related_name='head_of_vendor'` используется в `ForeignKey` модели `Vendor` для обозначения связи в обратном направлении от модели `Person`. Это позволяет обращаться к связанным объектам из `Person` напрямую, но, в данном случае, вам это возможно не потребуется.

Также стоит учитывать, что если ваш запрос построен таким образом, что извлекает большое количество связанных объектов, вы можете столкнуться с проблемами производительности из-за множественных запросов к базе данных (N+1 query problem). Для оптимизации запросов в Django используйте методы `select_related` и `prefetch_related`, которые помогут уменьшить количество SQL-запросов к базе данных за счет объединения данных в начальных запросах.
Надо делать это вычисляемым полем, например. Зачем филд? А если надо для оптимизации, чтоб не делать каждый раз запрос, то можно перекрыть сохранение и записывать ссылку. 
Ссылку на себя из модели делать можно, вместо класса указывается его имя в виде строки.
В каждом туториале по джанго такие примеры есть. А если каких-то нет, а вам-новичку это зачем-то надо, то впору задуматься а правильно ли так поступать. Обычно все правильные пути давно исхожены, дорожки проторены и снабжены горой примеров и документацией. Маловероятно, что в начале своего пути вы столкнулись с каким-то редким сложным кейсом, который не ражеван сообществом вдоль и поперёк.
Похожие вопросы