I have this code for rating lessons, user and lesson should be added automatically from request authorization and URL:
#views.py
class RatingViewSet(
mixins.ListModelMixin,
mixins.CreateModelMixin,
viewsets.GenericViewSet
):
permission_classes = [permissions.IsAuthenticated]
serializer_class = RatingSerializer
def perform_create(self, serializer):
lessonInstance = Lesson.objects.get(id = self.kwargs['lessonID'])
serializer.save(user=self.request.user, lesson = lessonInstance)
def get_queryset(self):
lessonID = self.kwargs['lessonID']
return Rating.objects.filter(user=self.request.user, lesson=lessonID)
#serializers.py
class RatingSerializer(serializers.ModelSerializer):
class Meta:
model = Rating
fields = ('id', 'lesson','user', 'difficulty')
read_only_fields = ('id', 'user','lesson')
#models.py
class Rating(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
lesson = models.ForeignKey('lessons.Lesson')
difficulty = models.IntegerField()
class meta:
unique_together('user','lesson')
I want to have max 1 rating per user/lesson, hence unique_together('user','lesson')
. But there is a problem: as long as that constraint is in the code, requests without user
or lesson
fields get denied with field required
error, even though they are read_only
.
(If I migrate with unique_together('user','lesson')
, then delete that line it works, but as soon as it's there I get errors.)
I want to keep that bit of code there so I don't accidentally remove the unique_together
constraint on later migrations.
If a field is
read_only=True
then thevalidated_data
will ignore data of it => Causeerror required field
, read more at docI also met this issue in a similar context, then tried @iulian's answer above but with no luck! This combo
read_only
+default
behavior is not supported anymore, check thisI resolved this issue by 2 solutions:
Solution 1. Write your own
CurrentUserDefault
class to get the user id then set to default attribute data of serializer(Ref from #51940976)Solution 2. Override the create method of serializer to set data for user id(Ref from this)
I hope this helps!
This is a special-case that requires a different approach. Here's what
django-rest-framework
documentation (see the Note) says about this case:In your case, you need to explicitly define the
user
andlesson
fields on yourRatingSerializer
, like this:Good luck!