gpt4 book ai didi

python - 编写 django Rest 序列化器时遇到的问题

转载 作者:太空宇宙 更新时间:2023-11-03 20:27:22 25 4
gpt4 key购买 nike

我正在尝试编写一个 Django Rest Framework 序列化器。它应该接受简单的原始数据并返回带有一些相关对象数据的数据。我正在序列化的模型是 Model_C

以下是模型:

class ModelA(models.Model):
name = models.Charfield(max_length=16)
attr1 = models...
...

class ModelB(models.Model):
name = models.CharField(max_length=16)
attr1 = models...
...

class ModelC(models.Model):
model_a = models.ForeignKey(ModelA)
model_b = models.ForeignKey(ModelB)
text = models.CharField(max_length=32)
date = models.DateTimeField()

这是 API View :

class ModelCApiView(RetrieveUpdateDestroyAPIView):
serializer_class = ModelCSerializer

def get_queryset(self):
return self.serializer_class.Meta.model.objects.all()

def post(self, request):
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(data=serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

馈送到序列化器的数据如下(带或不带 ID):

{'id': '1', 'model_a': 1, 'model_b': 1, 'text': 'some text', 'date': '2019-08-28 08:00:00'}

现在,序列化器应该保存实例并返回带有一些相关数据的序列化模型:

{'id': '1', 'model_a': {'id': 1, 'name': 'some model a name'}, 'model_b': {'id': 1, 'name': 'some model b name', 'attr1': 'some attr value'}, 'text': 'some text', 'date': '2019-08-28 08:00:00'}

所以唯一创建的是 ModelC 实例。 api View 不应创建 ModelA 或 ModelB 实例。

主要问题在于序列化/反序列化对象。我已经尝试过几件事:

  1. 最简单的
class ModelCSerializer(serializers.ModelSerializer):
class Meta:
model = ModelC
fields = "__all__"

它正确地反序列化请求,保存实例,但返回的信息太少 - 仅相关对象的 ID。

<小时/>
  • 我使用了深度
  • class ModelCSerializer(serializers.ModelSerializer):
    class Meta:
    model = ModelC
    fields = "__all__"
    depth = 1

    这不起作用,因为它会输出 500 并显示错误:“Column 'model_a_id' can not be null”。

    <小时/>
  • 我尝试添加到 2. 声明的序列化器:
  • class ModelCSerializer(serializers.ModelSerializer):
    class Meta:
    model = ModelC
    fields = "__all__"
    depth = 1
    model_a = ModelASerializer()
    model_b = ModelBSerializer()

    这会产生错误 400,错误的请求,因为它要求我将 model_a 和 model_b 的所有数据作为字典插入。

    <小时/>
  • 我向 APIView 添加了几行代码,以使用简单的序列化器序列化数据,然后使用更高级的序列化器再次序列化并返回更多信息。
  •     serializer = ModelCSerializer

    def post(self, request):
    serializer = self.get_serializer(data=request.data)
    if serializer.is_valid():
    obj = serializer.save()
    serializer = ModelCReadOnlySerializer(instance=obj, data=serializer.data)
    serializer.is_valid()
    return Response(data=serializer.data, status=status.HTTP_201_CREATED)
    else:
    return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)


    class ModelCReadOnlySerializer(serializers.ModelSerializer):
    class Meta:
    model = ModelC
    fields = ("id", "model_a", "model_b", "text", "date")
    read_only_fields = fields
    depth = 1

    这是最接近我的解决方案,因为它几乎返回了我需要的内容,除了它返回 model_a 和 model_b 的所有数据,这太多了。

    <小时/>

    此时我还有其他想法,但我敢打赌它们都很糟糕。我很高兴收到任何有关如何继续的提示,因为我已经很接近 -> || <- 自己在没有 DRF 的情况下编写所有内容:-)

    提前谢谢您。

    最佳答案

    在@dirkgroten的大力帮助下:

    第四条路是要走的路。首先,必须有两个序列化器:一个用于写入(按照 1),一个用于读取:

    class ModelCReadOnlySerializer(serializers.ModelSerializer):
    class Meta:
    model = ModelC
    fields = ("id", "model_a", "model_b", "text", "date")
    read_only_fields = fields
    # Not there is no depth any more
    model_a = ModelASerializer()
    model_b = ModelBSerializer()

    并且在 View 中,数据不需要传递到只读序列化器中:

    if serializer.is_valid():
    obj = serializer.save()
    serializer = ModelCReadOnlySerializer(instance=obj)
    return Response(data=serializer.data, status=status.HTTP_201_CREATED)
    else:
    return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    现在数据以简单的形式接收、处理和保存,然后返回更多详细信息。

    再次感谢!

    关于python - 编写 django Rest 序列化器时遇到的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57727702/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com