REST Django - Невозможно найти контекст запроса из моего валидатора
Пожалуйста, будьте мягче. Я новичок в Django, и уровень абстракции кажется мне просто подавляющим.
Моей конечной целью является изменение файла изображения по пути в модель. Эта часть может быть актуальна или не актуальна, но помощь пришла ко мне в этом посте, который подсказал мне, что я должен вносить изменения внутри валидатора: REST Django - Как изменить сериализованный файл до того, как он будет помещен в модель
В любом случае, на данный момент я просто пытаюсь получить контекст запроса, чтобы быть уверенным, что я могу делать вещи только тогда, когда запрос является POST. Однако, внутри моего валидатора, self.context - это просто пустой словарь. Исходя из того, что я нашел, для self.context['request'] должно быть значение. Вот что у меня есть:
Сериализатор с методом валидатора:
class MediaSerializer(serializers.ModelSerializer):
class Meta:
model = Media
fields = '__all__'
def validate_media(self, data):
print(self.context)
#todo: why is self.context empty?
#if self.context['request'].method == 'POST':
# print('do a thing here')
return data
def to_representation(self, instance):
data = super(MediaSerializer, self).to_representation(instance)
return data
Представление вместе с методом post
class MediaView(APIView):
queryset = Media.objects.all()
parser_classes = (MultiPartParser, FormParser)
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = MediaSerializer
def post(self, request, *args, **kwargs):
user = self.request.user
print(user.username)
request.data.update({"username": user.username})
media_serializer = MediaSerializer(data=request.data)
# media_serializer.update('username', user.username)
if media_serializer .is_valid():
media_serializer.save()
return Response(media_serializer.data, status=status.HTTP_201_CREATED)
else:
print('error', media_serializer.errors)
return Response(media_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Модель:
class Media(models.Model):
objects = None
username = models.ForeignKey(User, to_field='username',
related_name="Upload_username",
on_delete=models.DO_NOTHING)
date = models.DateTimeField(auto_now_add=True)
#temp_media = models.FileField(upload_to='upload_temp', null=True)
media = models.FileField(upload_to='albumMedia', null=True)
#todo: potentially this will go to a temp folder, optimize will be called and then permananent home will be used -jjb
#MEDIA_ROOT path must be /src/upload
file_type = models.CharField(max_length=12)
MEDIA_TYPES = (
('I', "Image"),
('V', "Video")
)
media_type = models.CharField(max_length=1, choices=MEDIA_TYPES, default='I')
ACCESSIBILITY = (
('P', "Public"),
('T', "Tribe"),
('F', "Flagged")
)
user_access = models.CharField(max_length=1, choices=ACCESSIBILITY, default='P')
Так что я просто пытаюсь понять, как решить эту проблему с контекстом. Кроме того, если есть другие советы о том, как попасть туда, куда я собираюсь, я буду очень признателен.
PS Я здесь совсем недавно. Если я написал этот вопрос неподходящим для stack overflow образом, пожалуйста, будьте добры, и я исправлю его. Спасибо.
Я не думаю, что вам нужно беспокоиться о проверке того, является ли запрос POST внутри метода validate_media(). Обычно проверка происходит только во время запросов POST, PATCH и PUT. Кроме того, проверка происходит только тогда, когда вы вызываете is_valid() на сериализаторе, часто явно в представлении, как вы делаете в вашей функции post(). Пока вы никогда не вызываете is_valid() ниоткуда, кроме как из post(), вы знаете, что это POST. Поскольку вы не поддерживаете patch() или put() в вашем представлении, то это не должно быть проблемой.
внутри моего валидатора, self.context - это просто пустой словарь
Чтобы сериализатор существовал, вы должны явно передать ему контекст при создании. Здесь нет никакой магии. Как вы можете видеть в исходном коде context по умолчанию используется {}, когда вы не передаете его.
Чтобы передать контекст, вы можете сделать следующее:
context = {'request': request}
media_serializer = MediaSerializer(data=request.data, context=context)
Еще лучше просто передать в методе:
context = {'method': request.method}
media_serializer = MediaSerializer(data=request.data, context=context)
Вы можете сделать словарь context таким, каким захотите.