在 django 中加入超过 2 table 的报告并从加入的 table 中提取所有字段

Joining more than 2 tables for reports in django and extract all the fields from the joined table

我正在加入 ClientDetails、AssignmentTable 和 CallDetails table 以查看特定客户已分配给哪个电话呼叫者并获得最新的呼叫详细信息。但是我无法使用 django ORM 来完成。

问题:

我正在尝试访问作业 table 中的字段并调用 table 但我只获得 ID 而不是其他字段。

问题:

如何从客户端 ID 为 1 的分配和调用详细信息 table 中提取所有列?

这是我想提出的 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,请确保在 prefetch_related()

中使用该名称而不是 model_set 进行访问