Django中关联HiringstatusSerializer与DriverEditListSerializer时出现AttributeError报错
解决Django序列化器关联Hiring模型时的AttributeError问题
你遇到的这个报错核心很明确:Driver模型实例并没有名为hstatus的属性,所以序列化器无法找到对应字段的值。这本质是因为你没有正确映射Driver和Hiring两个模型之间的关联关系,导致Django无法自动关联到对应的Hiring记录。
问题原因拆解
你的HiringstatusSerializer是基于Hiring模型定义的,但Driver模型本身和Hiring模型的关联没有在序列化器里做正确配置——要么是模型反向关联的名称不匹配,要么是没有手动指定字段的数据源。
针对性解决方案
根据你代码里Hiring模型包含driver_id字段的信息,我假设Hiring是通过外键关联到Driver的,下面分两种常见关联场景给出解决方法:
场景1:一个Driver对应一个Hiring(一对一关系)
如果你的Hiring模型用OneToOneField关联Driver,可以直接通过设置反向关联名称解决:
# models.py 示例 class Hiring(models.Model): driver = models.OneToOneField(Driver, on_delete=models.CASCADE, related_name='hstatus') status = models.CharField(max_length=50) # 其他字段...
设置related_name='hstatus'后,Driver实例会自动拥有hstatus属性,你原来的序列化器代码就可以正常工作了。
如果没设置related_name,也可以在序列化器里手动指定字段来源:
class DriverEditListSerializer(serializers.ModelSerializer): city = CitySerializer(read_only=True) location = LocationSerializer() # 手动指定数据源为Django默认的反向关联名(模型名小写) hstatus = HiringstatusSerializer(source='hiring', read_only=True) class Meta: model = Driver fields = ('id','employee_id','employer', 'name','uber_name','uber_device_no', 'mobile', 'location', 'city','shift','status', 'aadhar_no','hstatus')
场景2:一个Driver对应多个Hiring(一对多关系)
如果Hiring模型用ForeignKey关联Driver,需要在序列化器里加上many=True参数表示多条记录:
# models.py 示例 class Hiring(models.Model): driver = models.ForeignKey(Driver, on_delete=models.CASCADE, related_name='hstatus') status = models.CharField(max_length=50) # 其他字段...
修改序列化器:
class DriverEditListSerializer(serializers.ModelSerializer): city = CitySerializer(read_only=True) location = LocationSerializer() # 加上many=True表示对应多条Hiring记录 hstatus = HiringstatusSerializer(many=True, read_only=True) class Meta: model = Driver fields = ('id','employee_id','employer', 'name','uber_name','uber_device_no', 'mobile', 'location', 'city','shift','status', 'aadhar_no','hstatus')
自定义获取逻辑(灵活场景)
如果需要更灵活的控制(比如只返回最新的一条Hiring记录),可以用SerializerMethodField实现:
class DriverEditListSerializer(serializers.ModelSerializer): city = CitySerializer(read_only=True) location = LocationSerializer() hstatus = serializers.SerializerMethodField() def get_hstatus(self, obj): # 获取当前driver对应的最新Hiring记录 latest_hiring = obj.hiring_set.order_by('-id').first() # 未设置related_name时默认是hiring_set if latest_hiring: return HiringstatusSerializer(latest_hiring).data return None # 无记录时返回空值 class Meta: model = Driver fields = ('id','employee_id','employer', 'name','uber_name','uber_device_no', 'mobile', 'location', 'city','shift','status', 'aadhar_no','hstatus')
性能优化建议
为了避免数据库N+1查询问题,建议在视图的queryset里添加关联查询优化:
class DriverViewSet(viewsets.ModelViewSet): queryset = Driver.objects.filter(is_active=1) serializer_class = DriverEditListSerializer def get_queryset(self): queryset = Driver.objects.filter( is_active=1, city_id=self.request.GET.get('city_id') ).select_related('hstatus') # 一对一关系用select_related # 一对多关系替换为:.prefetch_related('hstatus') return queryset
内容的提问来源于stack exchange,提问作者Ashish Pandey
相关产品推荐
相关产品推荐

