#python #django #django-rest-framework
Вопрос:
У меня возникли проблемы с обработкой ошибки DoesNotExist, я использую DRF и DRF-Вложенные маршрутизаторы, и когда я создаю новый объект Like, мне нужна фотография PK, чтобы я мог добавить ее в объект Like.
Я пытаюсь поймать ошибку, которую я получаю, когда фотография с этим ПК не существует. Вот как я создаю подобное в сериализаторе:
class LikeModelSerializer(serializers.ModelSerializer):
""" Like model serializer. """
user = serializers.CharField(default=serializers.CurrentUserDefault())
class Meta:
""" Meta class. """
model = Like
fields = ('user', 'photo')
read_only_fields = ('user', 'photo')
def create(self, validated_data):
# Get the photo pk from the view context (DRF-nested-routers) and
# create the new like with the validated_data
photo_pk = self.context['view'].kwargs["photo_pk"]
try:
photo = Photo.objects.get(id=photo_pk)
except Photo.DoesNotExist:
return Response(data={'detail': "The photo doesn't exist."}, status=status.HTTP_404_NOT_FOUND)
validated_data["photo"] = photo
like, created = Like.objects.get_or_create(**validated_data)
if created:
photo.total_likes = 1
photo.save()
return like
perform_create представления:
def perform_create(self, serializer):
""" Creates a new like.
The substraction in the total_likes is made in the serializer.
"""
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(data=serializer.data, status=status.HTTP_200_OK)
Ответ, который я получаю на это, таков: {'user': 'my username here'}
Я тоже пробовал, except Photo.DoesNotExist
но это дает тот же результат.
Комментарии:
1. Можете ли вы поделиться данными запроса и всем сериализатором?
2. Вы написали:
photo_pk = self.context['view'].kwargs["photo_pk"]
, вы уверены, что контекст сериализатора содержит эти объекты? Пожалуйста, предоставьте полную информацию об ошибке.3. Я добавил больше кода, полный сериализатор и perform_create. Да, в контексте есть photo_pk, ошибка, которую я получаю
Photo.DoesNotExist: Photo matching query does not exist.
, Но это нормально, проблема в том, что я получаю неправильный ответ при попытке обработать эту ошибку. Ответ, который я получаю ({'user': 'my username here'}
), относитсяself.data
к сериализатору, если это поможет. Я не понимаю, почему это не дает ответной частиexcept DoesNotExist:
Ответ №1:
Возможно, будет более понятно выполнить проверку в методе validate класса сериализатора. В случае отсутствия фотографии поднимите serializers.ValidationError
свой .
Я не тестировал код, но думаю, что он работает.
class LikeModelSerializer(serializers.ModelSerializer):
...
def validate(self, attrs):
photo_pk = self.context['view'].kwargs["photo_pk"]
try:
photo = Photo.objects.get(id=photo_pk)
except Photo.DoesNotExist:
raise serializers.ValidationError({"detail": "The photo doesn't exist"})
attrs["photo"] = photo
return attrs
def create(self, validated_data):
# Get the photo pk from the view context (DRF-nested-routers) and
# create the new like with the validated_data
like, created = Like.objects.get_or_create(**validated_data)
if created:
photo.total_likes = 1
photo.save()
return like
def perform_create(self, serializer):
""" Creates a new like.
The substraction in the total_likes is made in the serializer.
"""
if not serializer.is_valid():
raise ValidationError(serializer.errors)
serializer.save()
return Response(data=serializer.data, status=status.HTTP_200_OK)
Комментарии:
1. Это работает! Но мне нужно было добавить
photo = Photo.objects.get(id=photo_pk)
в метод создания, и он уже выполняет этот запросvalidate()
, есть идеи, как я могу сделать это только один раз? Например, может быть, просто войтиvalidate()
, а затем передать его методу создания?