DRF序列化外键返回对象,而不是ID

swo*_*wor 5 python django django-rest-framework

我有一个一对多关系。一个建筑和多个相机。\n我想返回 CameraSerializer 中的所有建筑对象字段

\n

问题

\n

当我执行 POST 请求时(创建新的 Camera 对象)

\n
{\n    "name": "CameraName",\n    "url": "CameraUrl",\n    "building": 2\n    \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我有一个错误

\n
{\n    "building": {\n        "nonFieldErrors": [\n            "Invalid data. Expected a dictionary, but got int."\n        ]\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

错误原因 - Django 需要完整的构造对象,但我只想设置 ID

\n

我该如何修复该错误?

\n

模型.py

\n
class Construction(models.Model):\n    """ \xd0\x9e\xd0\xb1\xd1\x8a\xd0\xb5\xd0\xba\xd1\x82 \xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xb8\xd1\x82\xd0\xb5\xd0\xbb\xd1\x8c\xd1\x81\xd1\x82\xd0\xb2\xd0\xb0"""\n    developer = models.ForeignKey(\n        Developer, related_name="constructions", on_delete=models.CASCADE\n    )\n    name = models.CharField(max_length=100)\n    plan_image = models.ImageField(upload_to=name_image, blank=True, null=True)\n    ...\n\n    def __str__(self):\n        return self.name\n\nclass Camera(models.Model):\n    building = models.ForeignKey(\n        Construction, related_name="cameras", on_delete=models.CASCADE\n    )\n    name = models.CharField(max_length=100)\n    url = models.CharField(max_length=100)\n    ...\n\n    def __str__(self):\n        return self.name\n
Run Code Online (Sandbox Code Playgroud)\n

序列化器.py

\n
class ConstructionSerializer(serializers.ModelSerializer):\n    coordinates = MyPointField()\n    deadline = serializers.DateTimeField(format=TIME_FORMAT)\n    cameras_number = serializers.SerializerMethodField()\n    developer_name = serializers.SerializerMethodField()\n    events = serializers.SerializerMethodField()\n\n    class Meta:\n        model = Construction\n        fields = (\n            'id', 'developer', 'developer_name', 'name', 'plan_image', 'address', 'coordinates', 'deadline',\n            'workers_number', 'machines_number', 'cameras_number', 'events'\n        )\n        read_only_fields = ('workers_number', 'machines_number', 'cameras_number', 'events')\n\n    \n    def create(self, validated_data):\n        instance = super().create(validated_data=validated_data)\n        return instance\n\n\nclass CameraSerializer(serializers.ModelSerializer):\n    frames = FrameSerializer(many=True, read_only=True)\n    building = ConstructionSerializer()\n\n    class Meta:\n        model = Camera\n        fields = (\n            'id', 'building', 'name', 'url', 'zone_id_x', 'zone_id_y',\n            'proc_id', 'path_frames', 'frames'\n        )\n        read_only_fields = ('proc_id', 'path_frames', 'frames')\n    \n    def create(self, validated_data):\n        instance = super().create(validated_data=validated_data)\n        instance.set_proc_id()\n        instance.set_path_frame()\n        return instance\n
Run Code Online (Sandbox Code Playgroud)\n

视图.py

\n
class CameraView(viewsets.ModelViewSet):\n    serializer_class = CameraSerializer\n    queryset = Camera.objects.all()\n\n    def get_camera_create_serializer(self, *args, **kwargs):\n        kwargs["context"] = self.get_serializer_context()\n        return self.serializer_class(*args, **kwargs)\n\n    def create(self, request, *args, **kwargs):\n        serializer = self.get_camera_create_serializer(data=request.data)\n        serializer.is_valid(raise_exception=True)\n\n        self.perform_create(serializer)\n        headers = self.get_success_headers(serializer.data)\n        response = {"result": serializer.data}\n        return Response(\n            response, status=status.HTTP_201_CREATED, headers=headers\n        )\n
Run Code Online (Sandbox Code Playgroud)\n