You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django多表关联查询问题:如何获取Contact关联的Account名称

Django多表关联查询问题解决

问题描述

作为Django新手,我正在开发一款轻量CRM系统,使用MySQL数据库的关联实体处理多对多关系。目前通过关联实体contactdeal连接deal与contact表,已用select_related实现两者的关联查询,但无法通过Contact表中的account_id外键获取Account表对应的name字段值,寻求解决方法。

相关代码

Models

class Account1(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True)       
    address = models.CharField(max_length=255, blank=True, null=True)    
    city = models.CharField(max_length=255, blank=True, null=True)       
    state = models.CharField(max_length=255, blank=True, null=True)      
    country = models.CharField(max_length=255, blank=True, null=True)    
    description = models.CharField(max_length=255, blank=True, null=True)
    phone = models.CharField(max_length=255, blank=True, null=True)      
    email = models.CharField(max_length=255, blank=True, null=True)
    biztype = models.CharField(max_length=255, blank=True, null=True)
    notes = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'account'

class Contact1(models.Model):
    contact_id = models.AutoField(primary_key=True)
    first_name = models.CharField(max_length=255, blank=True, null=True)
    last_name = models.CharField(max_length=255, blank=True, null=True)
    account_id = models.ForeignKey(Account1, models.DO_NOTHING, db_column='account_id', blank=False, null=False)
    contact_notes = models.TextField(blank=True, null=True)
    contact_email = models.CharField(max_length=255, blank=True, null=True)
    contact_phone = models.CharField(max_length=255, blank=True, null=True)
    contact_status = models.CharField(max_length=255, blank=True, null=True)
    
    class Meta:
        managed = False
        db_table = 'contact'

class Contactdeal(models.Model):
    contactdeal_id = models.AutoField(primary_key=True)
    contactdeal_deal_fk = models.ForeignKey('Deal', models.DO_NOTHING, db_column='contactdeal_deal_fk', blank=True, null=True)
    contactdeal_contact_fk = models.ForeignKey(Contact1, models.DO_NOTHING, related_name='contactdeal_contact_fk', db_column='contactdeal_contact_fk', blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'contactdeal'

class Deal(models.Model):
    deal_id = models.AutoField(primary_key=True)
    deal_name = models.CharField(max_length=255, blank=True, null=True)
    est_value = models.DecimalField(max_digits=13, decimal_places=2, blank=True, null=True)
    deal_notes = models.TextField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'deal'

View

def deal(request):
    deal = Contactdeal.objects.select_related('contactdeal_contact_fk', 'contactdeal_deal_fk')
    template = loader.get_template('deal.html')
    context = {
        'deal' : deal,
    }
    return HttpResponse(template.render(context, request))

Template

{% for x in deal %}
<tbody>
<tr class="table-active">
    <td>{{x.contactdeal_deal_fk.deal_name}}</td>
    <td>{{x.contactdeal_deal_fk.est_value}}</td>
    <td>{{x.contactdeal_contact_fk.first_name}}</td>
    <td>{{x.contactdeal_contact_fk.account_id}}</td>
    <td><a href="updateaccount/{{ x.id }}">Update</a></td>
    <td><a href="deleteaccount/{{x.id}}">Delete</a></td>
</tr>
</tbody>
{% endfor %}

解决步骤

1. 扩展select_related实现嵌套关联查询

当前select_related只关联了contactdeal_contact_fk和contactdeal_deal_fk,但没有关联Contact1对应的Account1表。需要通过**双下划线__**嵌套指定深层关联,这样能一次性拉取所有需要的数据,避免多次查询数据库。

修改View中的查询语句:

def deal(request):
    deal = Contactdeal.objects.select_related(
        'contactdeal_contact_fk',
        'contactdeal_contact_fk__account_id',  # 嵌套关联Account1表
        'contactdeal_deal_fk'
    )
    template = loader.get_template('deal.html')
    context = {
        'deal' : deal,
    }
    return HttpResponse(template.render(context, request))

2. 在模板中正确调用Account的name字段

原来的模板中{{x.contactdeal_contact_fk.account_id}}只会输出Account的ID值,要获取对应的name字段,需要访问关联对象的属性:

修改模板中的对应行:

<td>{{x.contactdeal_contact_fk.account_id.name}}</td>

可选优化:优化外键字段名

如果觉得account_id作为外键字段名容易混淆(Django中,外键字段实际存储的是关联对象,数据库列名通过db_column指定),可以修改Contact1的外键定义,让字段名更直观:

# 修改Contact1中的外键字段
account = models.ForeignKey(Account1, models.DO_NOTHING, db_column='account_id', blank=False, null=False)

修改后,模板中可以写成:

<td>{{x.contactdeal_contact_fk.account.name}}</td>

这样代码可读性更强,也符合Django的命名习惯。


内容的提问来源于stack exchange,提问作者stcrmhelp775

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:20:37