Как объединить 3 или более 3 моделей в одном запросе ORM?

У меня есть 4 модели, связанные внешним ключом,

    username = None
    email = models.EmailField(('email address'), unique=True)
    phone_no = models.CharField(max_length=255, unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def __str__(self):
        return self.email

class personal_profile(models.Model):
    custom_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    picture = models.ImageField(default='profile_image/pro.png', upload_to='profile_image', blank=True)
    role = models.CharField(max_length=255, blank=True, null=True)
    gender = models.CharField(max_length=255, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)
    def __str__(self):
        return str(self.pk)

class academia_profile(models.Model):
    custom_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    education_or_certificate = models.CharField(max_length=255, blank=True, null=True)
    university = models.CharField(max_length=255, blank=True, null=True)
    def __str__(self):
        return str(self.pk)

class contact_profile(models.Model):
    custom_user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    country = models.CharField(max_length=255, blank=True, null=True)
    state = models.CharField(max_length=255, blank=True, null=True)
    city = models.CharField(max_length=255, blank=True, null=True)
    def __str__(self):
        return str(self.pk)

Для извлечения данных из этих четырех моделей, мне нужно извлечь их путем запроса 4 раза по-разному, а затем путем передачи различных переменных в HTML шаблоны это что-то суматошное плюс снизит скорость работы (я уверен!)

Мои текущие запросы выглядят следующим образом

    user_base = CustomUser.objects.get(id=user_id)
    user_personal = personal_profile.objects.get(custom_user=user_id)
    academia = academia_profile.objects.get(custom_user=user_id)
    contact = contact_profile.objects.get(custom_user=user_id)
<

Кроме того, я хочу извлечь только country из contact_profile и picture из personal_profile в запросе join.

Select_related() может работать здесь, но как? вот что я не понимаю.

Вы ищете prefetch_related:

Возвращает набор запросов, который автоматически извлекает в одном пакете связанные объекты для каждого из указанных поисков.

user_base = (
    CustomUser
    .objects
    .prefetch_related(           #<-- THIS!
        "personal_profile_set",
        "academia_profile_set",
        "contact_profile_set")
    .get(id=user_id))

personal_profile = user_base.personal_profile_set.all()[0]
academia_profile = user_base.academia_profile_set.all()[0]
contact_profile = user_base.contact_profile_set.all()[0]

Btw, если у вас только один личный_профиль, академический_профиль, контактный_профиль на CustomUser, подумайте о замене ForeignKey на OneToOneField и используйте выбор_родственного.

Вернуться на верх