Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django rest framework DRF序列化程序自定义创建_Django Rest Framework - Fatal编程技术网

Django rest framework DRF序列化程序自定义创建

Django rest framework DRF序列化程序自定义创建,django-rest-framework,Django Rest Framework,我不知道我这样做是否正确,但我在保存与DRF序列化程序的一些关系方面遇到了问题 假设我有一个留言板和一些留言板帖子 Post有一个序列化程序,如: class MessageBoardPostSerializer(serializers.ModelSerializer): class Meta: model = MessageBoardPost fields = '__all__' 我想通过发布到/api/messageBoards/[PK]/create\u Po

我不知道我这样做是否正确,但我在保存与DRF序列化程序的一些关系方面遇到了问题

假设我有一个留言板和一些留言板帖子

Post有一个序列化程序,如:

class MessageBoardPostSerializer(serializers.ModelSerializer):
  class Meta:
      model = MessageBoardPost
      fields = '__all__'
我想通过发布到/api/messageBoards/[PK]/create\u Post来添加帖子/ 为此,我在留言板视图集中添加了一个操作:

@action(detail=True, methods=['post'], permission_classes=[MatchesMessageboardVisibility])
def create_post(self, request, pk=None):
    # Messageboard to post to
    messageBoard = MessageBoard.objects.get(pk=pk)

    if messageBoard is not None:
        serializer = MessageBoardPostSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
    return Response(serializer.data)
由于MessageBoard是帖子上必需的FK,因此在viewset中创建帖子时会出现验证错误


解决此问题的最佳方法是什么?

您可以将留言板作为上下文传递给序列化程序:

views.py

从django.shortcuts导入获取对象或404 @actiondetail=True,方法=['post'],权限类=[MatchesMessageboardVisibility] def create_postself,请求,主键=无: 要发布到的留言板 留言板=获取对象或留言板,主键=主键 上下文={'message_board':message_board} serializer=MessageBoardPostSerializerdata=request.data,context=context serializer.is_validraise_exception=True 序列化程序.save 返回响应Serializer.data 序列化程序.py

类MessageBoardPostSerializers.ModelSerializer: 类元: model=MessageBoardPost 字段='\uuuu所有\uuuu' def createself,已验证的_数据: post=留言板post**已验证的\u数据 post.message\u board=self.context['message\u board'] 邮政储蓄 回程站
您可以将留言板作为上下文传递给序列化程序:

views.py

从django.shortcuts导入获取对象或404 @actiondetail=True,方法=['post'],权限类=[MatchesMessageboardVisibility] def create_postself,请求,主键=无: 要发布到的留言板 留言板=获取对象或留言板,主键=主键 上下文={'message_board':message_board} serializer=MessageBoardPostSerializerdata=request.data,context=context serializer.is_validraise_exception=True 序列化程序.save 返回响应Serializer.data 序列化程序.py

类MessageBoardPostSerializers.ModelSerializer: 类元: model=MessageBoardPost 字段='\uuuu所有\uuuu' def createself,已验证的_数据: post=留言板post**已验证的\u数据 post.message\u board=self.context['message\u board'] 邮政储蓄 回程站
序列化器我假设message_board是MessageBoardPost模型中的ForeignKey:

class MessageBoardPostSerializer(serializers.ModelSerializer):
  # this is read only by default which means serializer will not require that field 
  message_board = serializers.StringRelatedField() 

  class Meta:
      model = MessageBoardPost
      fields = '__all__'
视图集操作:

@action(detail=True, methods=['post'], permission_classes=[MatchesMessageboardVisibility])
def create_post(self, request, pk=None):
    # Messageboard to post to
    messageBoard = get_object_or_404(MessageBoard, pk=pk)

    serializer = MessageBoardPostSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)

    # here you can pass data without validation directly to the save method
    serializer.save(message_board=messageBoard)
    return Response(serializer.data)
你应该用snake\u case风格写变量,比如留言板等。 对于更高级的crud,您应该将url设置为类似/api/留言板/PK/posts/的位置,您将在此处发布您的帖子,并且留言板应该以过度引用的初始方法进行预取
序列化器我假设message_board是MessageBoardPost模型中的ForeignKey:

class MessageBoardPostSerializer(serializers.ModelSerializer):
  # this is read only by default which means serializer will not require that field 
  message_board = serializers.StringRelatedField() 

  class Meta:
      model = MessageBoardPost
      fields = '__all__'
视图集操作:

@action(detail=True, methods=['post'], permission_classes=[MatchesMessageboardVisibility])
def create_post(self, request, pk=None):
    # Messageboard to post to
    messageBoard = get_object_or_404(MessageBoard, pk=pk)

    serializer = MessageBoardPostSerializer(data=request.data)
    serializer.is_valid(raise_exception=True)

    # here you can pass data without validation directly to the save method
    serializer.save(message_board=messageBoard)
    return Response(serializer.data)
你应该用snake\u case风格写变量,比如留言板等。 对于更高级的crud,您应该将url设置为类似/api/留言板/PK/posts/的位置,您将在此处发布您的帖子,并且留言板应该以过度引用的初始方法进行预取
嗯,我有点快。。。确实也有一些麻烦。。。我想我应该添加一些自定义验证,或者在调用IsValidad时不引发异常。在评论中遇到一些问题,我可以帮助您编辑答案。我只是认为我们不需要在验证时引发异常。留言板是帖子上的必填字段。因为我们在保存时传递了它,所以验证已经抛出了一个异常。我来看看你的高级crud建议;-。谢谢如果数据不正确,应始终引发_异常。您能显示验证错误包含哪些字段吗?嗯。。尝试将序列化程序消息板字段更新为:serializers.PrimaryKeyRelatedFieldread\u only=True。当然,字段名留言板应该与模型字段名完全相同。尝试尝试使用message\u board\u id序列化程序字段名,如果没有帮助的话。。。确实也有一些麻烦。。。我想我应该添加一些自定义验证,或者在调用IsValidad时不引发异常。在评论中遇到一些问题,我可以帮助您编辑答案。我只是认为我们不需要在验证时引发异常。留言板是帖子上的必填字段。因为我们在保存时传递了它,所以验证已经抛出了一个异常。我来看看你的高级crud建议;-。谢谢如果数据不正确,应始终引发_异常。您能显示验证错误包含哪些字段吗?嗯。。尝试将序列化程序消息板字段更新为:serializers.PrimaryKeyRelatedFieldread\u only=True。当然,字段名留言板应该与模型字段名完全相同。如果没有帮助,请尝试使用message_board_id序列化程序字段名。