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."
]
}
精彩评论