Объединение более 2 таблиц для отчетов в django и извлечение всех полей из объединенной таблицы

Я объединяю таблицы ClientDetails, AssignmentTable и CallDetails, чтобы получить представление о том, к какому телеколлеру был приписан конкретный клиент, а также получить информацию о последних звонках. Однако я не могу добиться этого, используя django ORM.

ВЫПУСК:

Я пытаюсь получить доступ к полям в таблице назначений и таблице вызовов, но получаю только идентификаторы, а не другие поля.

Вопрос:

Как извлечь все столбцы из таблицы "Назначение и детали звонков", в которой id клиента равен 1?

Вот SQL-запрос, который я пытаюсь придумать:

SELECT t1.uid, t1.phone_number, t1.client_name, t1.base, t1.location, t2.assigner, t2.bpo_agent, t2.cro_agent, t3.bpo_status_id, t3.cro_status_id, t3.agent_id_id
FROM public.bpo_app_clientdetails t1
LEFT JOIN public.bpo_app_assignmentdetails t2 ON t1.uid = t2.client_id_id
LEFT JOIN public.bpo_app_calldetails t3 ON t1.uid = t3.client_id_id;

Ниже представлен файл модели:

class ClientDetails(models.Model):
    uid = models.AutoField(primary_key=True)
    phone_number = PhoneNumberField(unique=True)
    client_name = models.CharField(max_length=50, blank=True, null=True)
    base = models.CharField(max_length=50, blank=True, null=True)
    location = models.CharField(max_length=50, blank=True, null=True)

    class Meta:
        verbose_name_plural = "Client Contact Detail Table"

    def __str__(self):
        return f"{self.phone_number}, {self.client_name}"


class AssignmentDetails(models.Model):
    uid = models.AutoField(primary_key=True)
    client_id = models.ForeignKey(
            ClientDetails,
            on_delete=models.PROTECT,
            related_name='assignment_details'
    )
    date_and_time = models.DateTimeField(auto_now_add=True, blank=True)
    assigner = models.ForeignKey(
                                     User,on_delete=models.PROTECT,
                                     related_name='AssignerAgent',
                                     db_column='assigner',
                                 )
    bpo_agent = models.ForeignKey(
                                     User,on_delete=models.PROTECT,
                                     related_name='bpoAgent',
                                     db_column='bpo_agent',
                                 )

    cro_agent = models.ForeignKey(
                                     User,on_delete=models.PROTECT,
                                     related_name='croAgent',
                                     db_column='cro_agent',
                                 )

    class Meta:
        verbose_name_plural = "Client Assignment Detail Table"

    def __str__(self):
        return f"{self.uid}"

class CallDetails(models.Model):
    uid = models.AutoField(primary_key=True)
    date_and_time = models.DateTimeField(auto_now_add=True, blank=True)
    client_id = models.ForeignKey(
            ClientDetails,
            on_delete=models.PROTECT,
            related_name='call_details'
    )
    agent_id = models.ForeignKey(EmployeeDetails_lk,on_delete=models.PROTECT)

    bpo_status = models.ForeignKey(BpoStatus_lk,on_delete=models.PROTECT, blank=True, null=True)
    cro_status = models.ForeignKey(CroStatus_lk,on_delete=models.PROTECT, blank=True, null=True)

    required_loan_amt = models.CharField(max_length=50, blank=True, null=True)
    remarks = models.CharField(max_length=500, blank=True, null=True)
    loan_program = models.ForeignKey(LoanProgram_lk, on_delete=models.PROTECT, blank=True, null=True)
    disbursement_bank = models.ForeignKey(Banks_lk, on_delete=models.PROTECT, limit_choices_to={'loan_disbursement_status': True}, blank=True, null=True)

    class Meta:
        verbose_name_plural = "Client Call Detail Table"

    def __str__(self):
        return f"{self.uid}"
>>> qry=ClientDetails.objects.values('assignment_details','call_details').filter(uid=1)
>>> qry
<QuerySet [{'assignment_details': 1, 'call_details': None}]>
>>> print(a.query)
SELECT "bpo_app_assignmentdetails"."uid", "bpo_app_calldetails"."uid" FROM "bpo_app_clientdetails" LEFT OUTER JOIN "bpo_app_assignmentdetails" ON ("bpo_app_clientdetails"."uid" = "bpo_app_assignmentdetails"."client_id_id") LEFT OUTER JOIN "bpo_app_calldetails" ON ("bpo_app_clientdetails"."uid" = "bpo_app_calldetails"."client_id_id") WHERE "bpo_app_clientdetails"."uid" = 1

Вы можете использовать prefetch_related() для достижения этой цели. Я просто использую здесь некоторые примеры моделей для лучшего понимания.

class Company(models.Model):
    name = models.CharField(null=True, blank=True, max_length=100)

class Project(models.Model):
    name = models.CharField(null=True, blank=True, max_length=100)
    company = models.ForeignKey(Company, on_delete=models.CASCADE)

class Employee(models.Model):
    name = models.CharField(null=True, blank=True, max_length=100)
    company = models.ForeignKey(Company, on_delete=models.CASCADE)

В вашей функции views.py напишите следующие строки, чтобы получить желаемые результаты

companies = Company.objects.filter(id=1).prefetch_related('project_set', 'employee_set')
for company in companies:
    print(company.project_set.values()) # This will print this company projects
    print(company.employee_set.values()) # This will print this company employees

Примечание: Если вы используете related_name в отношениях ForeignKey, убедитесь, что вы обращаетесь с этим именем вместо model_set внутри prefetch_related()

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