开发者

This field is required DRF Nested Serializers

开发者 https://www.devze.com 2022-12-07 18:31 出处:网络
I\'m getting This field is required error while creating a nested serializer. I have ReviewRatings and ReviewImages models in which ReviewImages is FK to ReviewRatings so that an user can upload singl

I'm getting This field is required error while creating a nested serializer. I have ReviewRatings and ReviewImages models in which ReviewImages is FK to ReviewRatings so that an user can upload single or multiple images along with reviews. And the problem arises when i don't add required=True in serializer. If it's False then there is no problem at all.

#Models.py


class ReviewRatings(models.Model):
    user = models.ForeignKey(Account, on_delete=models.CASCADE)
    product = models.ForeignKey(Products, on_delete=models.CASCADE)
    rating = models.FloatField(validators=[MinValueValidator(0), MaxValueValidator(5)])
    created_at = models.DateField(auto_now_add=True)
    review = models.CharField(max_length=500, null=True)
    updated_at = models.DateField(auto_now=True)

    class Meta:
        verbose_name_plural = "Reviews & Ratings"

    def __str__(self):
        return self.product.product_name


class ReviewImages(models.Model):
    review = models.ForeignKey(
        ReviewRatings,
        on_delete=models.CASCADE,
        related_name="review_images",
        null=True,
        blank=True,
    )
    images = models.ImageField(upload_to="reviews/review-images", null=True, blank=True)

    def __str__(self):
        return str(self.images)

#Serializers.py


class ReviewImagesSerializer(ModelSerializer):
    class Meta:
        model = ReviewImages
        fields = ["images"]


class ReviewSerializer(ModelSerializer):
    user = SerializerMethodField()
    review_images = ReviewImagesSerializer(many=True, required=False)

    class Meta:
        model = ReviewRatings
        fields = [
            "user",
            "rating",
            "review",
            "created_at",
            "updated_at",
            "review_images",
        ]

    def get_user(self, obj):
        retu开发者_如何学Crn f"{obj.user.first_name} {obj.user.last_name}"

    def validate(self, obj):
        review_images = self.context["images"]
        max_size = [5 * 1024 * 1024]
        rev_img_size = [i.size for i in review_images]
        if rev_img_size > max_size:
            raise ValidationError({"error": "Size cannot exceed 5 MB"})
        elif len(review_images) > 3:
            raise ValidationError({"error": "you cant upload more than 3 photos"})
        return obj

    def create(self, validated_data):
        review_images = self.context["images"]
        reviews = ReviewRatings.objects.create(**validated_data)
        for image in review_images:
            ReviewImages.objects.create(review=reviews, images=image)
        return reviews

#Views.py

class SubmitReview(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request, product_slug):
        data = request.data
        review_images = request.FILES.getlist("review_images")
        if data["rating"] == "" and data["review"] == "":
            raise ValidationError({"detail": "Fields cannot be blank"})
        product = Products.objects.get(slug=product_slug)
        if ReviewRatings.objects.filter(
            user=request.user, product__slug=product_slug
        ).exists():
            return Response({"detail": "You have already submitted the review "})
        serializer = ReviewSerializer(
            data=request.data, context={"request": request,'images':review_images}
        )
        if serializer.is_valid():
            serializer.save(user=request.user, product=product)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors)

In this am getting list of images(Multiple image upload) and for that I had to do review_images = request.FILES.getlist("review_images") and pass it in context to ReviewRatingSerializer.

So if I dont have required=False in review_images = ReviewImagesSerializer(many=True, required=False) in ReviewRatingSerializer then the review along with images get created, otherwise required=True then the response will be

{
    "review_images": [
        "This field is required."
    ]
}
0

精彩评论

暂无评论...
验证码 换一张
取 消