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

在Django中获取外键关联的ClientType.name值问题求助

问题解决:通过外键获取关联模型字段并返回JSON

问题描述

需要通过Clients表的外键ID获取关联的ClientType.name值,传递给JsonResponse,但使用select_related后报错:
AttributeError: 'str' object has no attribute '_meta'

原视图代码:

def patientdetails(request):
    patient_id = request.POST.get('patient')
    context = {
       'company' : Clients.objects.filter(id=patient_id).select_related()
    }
    qs_json = serializers.serialize('json', context)
    return JsonResponse({'data': qs_json})

Models代码:

class ClientType(models.Model):
    name = models.CharField(max_length=128, blank=True, null=True)
    is_active = models.BooleanField(default=True)
    created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True, auto_now=True)

    class Meta:
        managed = True
        db_table = 'client_type'


class Clients(models.Model):
     client_type = models.ForeignKey(ClientType, models.DO_NOTHING)
     first_name = models.CharField(max_length=128, blank=True, null=True)
     middle_name = models.CharField(max_length=128, blank=True, null=True)
     last_name = models.CharField(max_length=128, blank=True, null=True)
     birthdate = models.DateField(blank=True, null=True)
     sex = models.CharField(max_length=128, blank=True, null=True)
     address = models.CharField(max_length=128, blank=True, null=True)
     occupation = models.CharField(max_length=128, blank=True, null=True)

     class Meta:
         managed = True
         db_table = 'clients'

原前端处理代码:

}).done(function(data){
      var resultdata = JSON.parse(data.data);
});

错误原因

  1. serializers.serialize参数错误:serializers.serialize()要求传入QuerySet或模型实例,而你传入的是字典context,这会导致序列化时识别错误,触发'str' object has no attribute '_meta'异常。
  2. select_related未指定关联字段:select_related()没有明确指定要关联的外键字段(client_type),虽然不会直接报错,但会导致查询效率低下,且无法确保关联数据被正确加载。
  3. 返回数据格式冗余:直接序列化QuerySet再转JSON会生成嵌套结构,前端需要额外解析,且默认序列化不会包含外键关联的具体字段值。

解决方案

修改视图代码

直接构造包含关联字段的字典,避免使用serializers.serialize()的冗余处理,同时明确指定关联字段:

from django.http import JsonResponse
from .models import Clients

def patientdetails(request):
    patient_id = request.POST.get('patient')
    # 获取单个客户对象,预加载关联的client_type数据
    client = Clients.objects.filter(id=patient_id).select_related('client_type').first()
    
    if not client:
        return JsonResponse({'data': None})
    
    # 构造包含关联字段的响应数据
    client_data = {
        'id': client.id,
        'first_name': client.first_name,
        'middle_name': client.middle_name,
        'last_name': client.last_name,
        'birthdate': client.birthdate.strftime('%Y-%m-%d') if client.birthdate else None,
        'sex': client.sex,
        'address': client.address,
        'occupation': client.occupation,
        'client_type_name': client.client_type.name  # 直接获取关联的ClientType名称
    }
    
    return JsonResponse({'data': client_data})

修改前端处理代码

现在返回的data.data是直接的JSON对象,无需额外解析:

}).done(function(data){
    var resultdata = data.data;
    // 直接使用关联字段,例如:
    // console.log(resultdata.client_type_name);
});

关键修改点

  • 使用select_related('client_type')明确指定预加载的外键关联,减少数据库查询次数,提升性能。
  • 用.first()获取单个客户对象(符合patient_id对应唯一客户的场景),避免返回QuerySet带来的冗余。
  • 手动构造响应字典,直接包含client_type.name,让前端可以直接使用目标字段。
  • 移除错误的serializers.serialize()调用,避免参数类型不匹配的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:33:09