首页 > 解决方案 > django rest 框架 - POST 请求导致 400 状态码

问题描述

我正在尝试执行一个 POST 请求来创建一篇文章,但我收到了这个错误Request failed with status code 400 Bad Request: /api/articles/create/

一篇文章需要创建3个属性:
(1)标题
(2)正文
(3)作者(当前用户)

路由器工作正常,因为 POST 请求进入post了类的方法ArticleCreateView。但我猜这serializer.is_valid()是由于某种原因而回归False。也print(request.data)返回{'title': 'hello', 'body': 'stuff'}

关于 Django 的另一个谜团是,序列化程序如何知道我是否想要获取、创建或更新某些内容?在我见过的所有示例中,序列化程序似乎神奇地知道这一点。

class ArticleCreateView(CreateAPIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors)


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'

    def create(self, validated_data):
        author = self.context['request'].user
        title = validated_data.get('title')
        body = validated_data.get('body')
        return Article.objects.create(author=author, title=title, body=body)


class Article(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    body = models.TextField(max_length=100)
    date_updated = models.DateTimeField(auto_now=True)
    date_created = models.DateTimeField(auto_now_add=True)

标签: djangomodel-view-controllerdjango-rest-frameworkserializationdjango-serializer

解决方案


根据您的序列化程序,验证过程需要author不通过 POST 有效负载的详细信息。
因此,通过在 Meta 类中添加或使用或指定,使author序列化程序中的字段成为不需要的字段。还像@nishant提到的那样传递上下文数据required=FalseReadOnlyField()read_only_fields

# views.py
class ArticleCreateView(CreateAPIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        serializer = ArticleSerializer(data=request.data, context={"request": request}) # change here 
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors)
# serializer.py
class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'
        read_only_fields = ('author',)

    def create(self, validated_data):
        author = self.context['request'].user
        title = validated_data.get('title')
        body = validated_data.get('body')
        return Article.objects.create(author=author, title=title, body=body)

推荐阅读