【问题标题】:How to add a serializer field in DRF for GET only not POST?如何在 DRF 中为 GET 添加序列化器字段而不是 POST?
【发布时间】:2019-11-07 13:42:51
【问题描述】:

我正在处理现有的 DRF 代码库,并希望添加 last_build 字段以仅返回 GET 请求。我不希望这影响与 POST 请求有关的任何事情。我创建了一个返回我正在寻找的字段的方法,并成功测试了它返回我想要的数据,但是我还没有测试这是否会影响现有的 POST 请求。

class JobSerializer(serializers.ModelSerializer):
    name = serializers.CharField(required=True, max_length=150)
    product = ProductSerializer(many=False, required=True)
    platform = PlatformSerializer(many=False, required=True)
    stages = StageSerializer(many=True, required=False)
    last_build = serializers.SerializerMethodField()

    def get_last_build(self, name):
        latest_build = JobExecution.manager.filter(job__name=name.name)
        return latest_build.last().build_id

    class Meta:
        model = Job
        fields = ("name", "product", "platform", "stages", "last_build")
        validators = [
            UniqueTogetherValidator(
                queryset=Job.manager.all(), fields=("name", "platform", "product")
            )
        ]

    def create(self, validated_data):
        # Create objects from data
        try:
            product_data = validated_data.pop("product", None)
            if product_data:
                ps = ProductSerializer()
                validated_data["product"] = ps.create(product_data)
            else:
                logger.exception("product is not valid")

            platform_data = validated_data.pop("platform", None)
            if platform_data:
                ps = PlatformSerializer()
                validated_data["platform"] = ps.create(platform_data)
            else:
                logger.exception("platform is not valid")

            stage_data = validated_data.pop("stages", [])
            stages = []

            the_job = Job.manager.get_or_create(**validated_data)[0]
            if stage_data:
                for stage_data in stage_data:
                    ss = StageSerializer()
                    stage_data["job"] = the_job
                    the_stage = ss.create(stage_data)
            return the_job
        except Exception as e:
            logger.exception(e)
            raise e

这里是 post 的 api 视图的 sn-p:

class JobView(GenericAPIView):
    def post(self, request, format=None):
        serializer = JobSerializer(data=request.data)
        logger.debug(request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            logger.info("POST request for Job failed: %s", serializer.errors)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

【问题讨论】:

  • 您需要从 GET 请求中排除/添加哪个字段?
  • 在不了解last_build的情况下创建作业
  • last_build,抱歉忘记指定
  • 因为该字段是SerializerMethodField,它不会影响任何 POST/PUT/PATCH 请求。

标签: django django-rest-framework


【解决方案1】:

您可以为 POST/PUT/PATCH 请求的跳过的序列化方法添加一些字段。 为跳过检查数据添加 required=False,为跳过 POST 请求添加 read_only=True

例子:

class JobSerializer(serializers.ModelSerializer):
    name = serializers.CharField(required=True, max_length=150)
    product = ProductSerializer(many=False, required=True)
    platform = PlatformSerializer(many=False, required=True)
    stages = StageSerializer(many=True, required=False)
    last_build = serializers.SerializerMethodField(required=False, read_only=True)

【讨论】:

    猜你喜欢
    • 2019-03-16
    • 2021-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多