【问题标题】:Not Null constrained error on field handled in views.py在views.py中处理的字段上的非空约束错误
【发布时间】:2020-06-30 10:15:57
【问题描述】:

我正在使用 django rest 框架。我有产品和评论模型。评论与产品相关;

class Product(models.Model):
    name = models.CharField(max_length=200, null=False, blank=False)
    description = models.TextField(max_length=2000, null=False, blank=False)
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    slug = models.SlugField(unique=True)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    is_featured = models.BooleanField(default=False)
    created= models.DateTimeField(auto_now_add=True)

class Review(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    product= models.ForeignKey(Product, on_delete=models.CASCADE)
    title = models.CharField(max_length=80, blank=False, null=False)
    body = models.TextField(max_length=400, blank=False, null=False)
    is_approved = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)

我为审查编写了一个序列化程序类:

class ReviewSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    class Meta:
        model = Review
        fields = ['id', 'author', 'title', 'body', 'is_approved', 'created']

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

在我的views.py中,我有这个;

class ReviewCreateView(CreateAPIView):
    serializer_class = ReviewSerializer
    queryset = Review.objects.all()
    permission_classes = [IsAuthenticated,]
    authentication_classes = [TokenAuthentication,]

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        product_id = kwargs.get('product')
        product = Product.objects.get(id=product_id)
        serializer.save(product=product)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

在我的网址 urlpatterns:

path('api/review/new/<product>/', ReviewCreateView.as_view(), name="create-review"),

问题是当我从前端向该 api 发送评论时,我不断收到 Not Null 约束错误,如下所示: IntegrityError at /api/review/new/23/ NOT NULL constraint failed: products_review.product_id

我已经在我的视图中处理了 CreateAPIView 中的产品保存,但由于某些原因 Django 没有选择它。请问我该怎么做?任何帮助将不胜感激。请注意,我在这里找到的类似问题的答案对我不起作用。

【问题讨论】:

  • 在视图中调用序列化程序.save()会创建一个新实例,但是你saved也在Serializer.create方法中使用create,这里你只需要返回一个准备保存的实例
  • @minglyu 谢谢。你的意思是在序列化程序中我不应该保存?

标签: python django django-rest-framework


【解决方案1】:

你几乎是对的。您传递了产品实例,因此它应该包含在 ReviewSerializer.create 方法的 valid_data 中。但在实际创建评论实例时不会使用它。

class ReviewSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    class Meta:
        model = Review
        fields = ['id', 'author', 'title', 'body', 'is_approved', 'created']

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

https://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

另外,你为什么不能在你的评论序列化器上有一个产品字段?

【讨论】:

  • 谢谢@c6754。我在 url 中将产品作为 kwarg 传递,使用产品 ID,而不是作为请求数据的一部分,所以我认为它不会成为验证数据的一部分。
  • 能否在Review.objects.create方法被调用之前打印出ReviewSerializer.create方法中product的值?
  • 我认为@c6754 是对的。 Review.objects.create(title=title, body=body, author=author) 尝试保存评论,但您还没有产品。尝试使用Review(title=title, body=body, author=author) 创建一个未保存的实例,然后在设置产品后保存在视图中。
猜你喜欢
  • 1970-01-01
  • 2020-06-19
  • 2015-08-07
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2012-11-02
  • 2020-03-17
  • 1970-01-01
相关资源
最近更新 更多