Как ограничить сериализацию в Django Rest Framework?
У меня есть 2 сериализатора, которые добавляют и вычитают (они одинаковые, с разницей в том, что add +=1 и subtract -=1) точки к ответу. Я хочу ограничить их так, чтобы пользователь мог использовать add point к ответу только один раз. Есть ли у вас идеи, как добраться до этого в Django Rest Framework?
class Answer(models.Model):
number_of_points = models.IntegerField(default=0)
class SubtractPointsSerializer(serializers.ModelSerializer):
class Meta:
model = Answer
fields = ('number_of_points',)
def update(self, instance, validated_data):
instance.number_of_points -= 1
instance.save()
return instance
Internal Server Error: /api/v1/answers/2/addpoints
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/generics.py", line 226, in put
return self.update(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/mixins.py", line 68, in update
self.perform_update(serializer)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/mixins.py", line 78, in perform_update
serializer.save()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/rest_framework/serializers.py", line 200, in save
self.instance = self.update(self.instance, validated_data)
File "/Users/jakubstrawa/programming/gitlabdeor/api/questions/serializers.py", line 74, in update
if not instance.addition_done and self.request.user not in instance.voters.all():
AttributeError: 'AddPointsSerializer' object has no attribute 'request'
Вы всегда можете добавить поле Boolean, которое хранит, было ли произведено сложение/вычитание. Вы можете хранить все User, которые уже голосовали, так что никто не будет голосовать дважды (также не будет голосовать за оба +1/-1).
class Answer(models.Model):
number_of_points = models.IntegerField(default=0)
addition_done = models.BooleanField(default=False)
subtraction_done = models.BooleanField(default=False)
voters = models.ManyToManyField('User', default=None, blank=True)
===========================================================
class SubtractPointsSerializer(serializers.ModelSerializer):
...
def update(self, instance, validated_data):
if not instance.subtraction_done:
instance.number_of_points -= 1
instance.subtraction_done = True
instance.save()
return instance
Вы также можете разделить поле ManyToMany на два отдельных (одно для сложения, другое для вычитания).