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

如何在DRF序列化器中将employee属性设为只读并指定对应值?

问题描述

现有如下Django REST Framework序列化器:

class MySerializer(serializers.ModelSerializer):
    class Meta:
        model = models.MyClass

对应的模型类:

class MyClass(models.Model):
    employee = models.ForeignKey("Employee", on_delete=models.CASCADE)
    work_done = models.TextField(blank=True, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

需求:

  • 将employee字段设置为只读
  • 该字段仅显示当前请求用户对应的Employee实例(即通过Employee.objects.get(user=self.request.user)获取的对象)
实现方案

方法一:序列化器内重写to_representation方法

直接在序列化器中完成字段只读设置与数据过滤:

class MySerializer(serializers.ModelSerializer):
    # 标记employee为只读字段
    employee = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = models.MyClass
        fields = ['employee', 'work_done', 'created_at', 'updated_at']

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        request = self.context.get('request')
        
        if request and hasattr(request, 'user'):
            try:
                current_employee = models.Employee.objects.get(user=request.user)
                # 仅保留当前用户对应的employee数据,不匹配则置空或移除字段
                if representation['employee'] != current_employee.pk:
                    representation['employee'] = None
            except models.Employee.DoesNotExist:
                # 处理用户未关联Employee的异常情况
                representation['employee'] = None
        
        return representation

方法二:视图层配合处理(更高效)

将数据过滤逻辑放在视图层,序列化器仅负责只读展示,减少序列化阶段的开销:

序列化器代码

class MySerializer(serializers.ModelSerializer):
    employee = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = models.MyClass
        fields = ['employee', 'work_done', 'created_at', 'updated_at']

创建视图(以CreateAPIView为例)

class MyCreateView(generics.CreateAPIView):
    serializer_class = MySerializer

    def perform_create(self, serializer):
        # 关联当前用户对应的Employee实例
        current_employee = models.Employee.objects.get(user=self.request.user)
        serializer.save(employee=current_employee)

查询视图(以ListAPIView为例)

class MyListView(generics.ListAPIView):
    serializer_class = MySerializer

    def get_queryset(self):
        # 直接从数据库过滤出当前用户Employee关联的数据
        current_employee = models.Employee.objects.get(user=self.request.user)
        return models.MyClass.objects.filter(employee=current_employee)

方案说明

  • 方法一适合需要对每条返回数据单独做校验的场景,但需注意捕获Employee.DoesNotExist异常,避免请求报错。
  • 方法二从数据库层面直接过滤数据,性能更优,是推荐的常规做法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:15:45