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

Django REST Framework:如何在VacationSerializer中嵌套关联员工数据?

解决Django REST Framework嵌套员工数据到休假序列化器的问题

问题根源

你之前的尝试存在两个关键错误:

  1. 模型中Vacation的外键命名与反向关联设置不合理,导致序列化器无法正确关联员工数据
  2. 序列化器错误使用many=True,单个休假仅对应一名员工,无需启用多对象序列化

具体修改步骤

1. 修正模型(models.py)

先规范外键字段命名与反向关联名称:

class Vacation(models.Model):
    start_date = models.DateField()
    end_date = models.DateField()
    # 将原字段名employee_id改为employee,Django会自动在数据库生成employee_id字段
    # related_name设为'vacations',表示从Employee对象访问其休假记录时用employee.vacations
    employee = models.ForeignKey(Employee, related_name='vacations', on_delete=models.PROTECT)

    def __str__(self):
        return f'{self.start_date} - {self.end_date}'

    @property
    def date_diff(self):
        return (self.end_date - self.start_date).days

注:若已完成过数据库迁移,需生成新的迁移文件并执行迁移;若不想修改数据库字段,可保留employee_id作为外键字段名,后续序列化器需对应调整。

2. 修正序列化器(serializer.py)

移除many=True,确保关联字段与模型外键一致:

class VacationSerializer(serializers.ModelSerializer):
    # 此处employee对应模型中的外键字段名,无需many=True
    employee = EmployeeSerializer(read_only=True)
    
    class Meta:
        model = Vacation
        fields = ('pk', 'start_date', 'end_date', 'employee')

若保留模型外键字段名为employee_id,序列化器需改为:

class VacationSerializer(serializers.ModelSerializer):
    employee = EmployeeSerializer(source='employee_id', read_only=True)
    
    class Meta:
        model = Vacation
        fields = ('pk', 'start_date', 'end_date', 'employee_id', 'employee')

3. 优化视图查询(views.py)

使用select_related预加载关联员工数据,避免N+1查询问题:

@api_view(['GET', 'POST'])
def vacations_list(request):
    if request.method == 'GET':
        # 用select_related提前加载employee数据
        data = Vacation.objects.all().select_related('employee')
        serializer = VacationSerializer(data, many=True)
        return Response(serializer.data)

效果验证

修改完成后,访问休假列表接口时,返回的JSON会包含嵌套的员工信息,示例格式如下:

[
    {
        "pk": 1,
        "start_date": "2024-01-01",
        "end_date": "2024-01-10",
        "employee": {
            "pk": 1,
            "first_name": "John",
            "surname": "Doe",
            "patronymic": "Smith",
            "birthday": "1990-01-01",
            "email": "john.doe@example.com",
            "position": "Developer",
            "phone_number": "1234567890"
        }
    }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:05:14