Используя Django REST framework generic ListCreateAPIView
, я создал конечную точку, которая, я думаю, должна иметь возможность загружать фотографии через запросы POST. Я моделирую свой код этот учебник.
До сих пор я пытался отправить файл POST на эту конечную точку, используя как Android, так и curl, и наблюдал такое же поведение: создается новая запись, но файл не подключен. Поскольку файл является обязательным, сервер затем возвращает ошибку 500.
Вот мой взгляд Django:
class PhotoList(generics.ListCreateAPIView):
model = Photo
serializer_class = PhotoSerializer
permission_classes = [
permissions.AllowAny
]
... моя модель:
def get_unique_image_file_path(instance=None, filename='dummy.jpg'):
"""
function to determine where to save images. assigns a uuid (random string) to each and places it
in the images subdirectory below media. by default, we assume the file is a .jpg
"""
ext = filename.split('.')[-1]
filename = "%s.%s" % (uuid.uuid4(), ext)
# TODO: 'images' is hard coded
return os.path.join('images', filename)
class Photo(models.Model):
post = models.ForeignKey(Post, related_name='photos', null=True, blank=True)
image = models.ImageField(upload_to=get_unique_image_file_path)
def get_image_abs_path(self):
return os.path.join(settings.MEDIA_ROOT, self.image.name)
... и мой сериализатор:
class PhotoSerializer(serializers.ModelSerializer):
image = serializers.Field('image.url')
class Meta:
model = Photo
Воспроизведение ошибки
Чтобы сгенерировать поведение, я отправляю сообщение на сервер с помощью следующей команды curl
(точно так же происходит с моим кодом клиента Android):
curl --form [email protected]_image.jpg http://localhost:8000/rest_tutorial/photos
В generics.ListCreateAPIView
метод create()
выглядит следующим образом:
# Copied from rest_framework.mixins.CreateModelMixin
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.DATA, files=request.FILES)
if serializer.is_valid():
self.pre_save(serializer.object)
self.object = serializer.save(force_insert=True)
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Когда я перехожу через указанный выше код в отладчике PyCharm, я могу отчетливо видеть мой файл в поле serializer init_files
после serializer.get_serializer()
. Однако в поле serializer object
есть куча трассировок, но ссылки на мой файл изображения отсутствуют. Может, здесь что-то не так?
После self.object = serializer.save(force_insert=True)
запись создается с пустым полем изображения, файл не загружается, а self.object.image.file
просто содержит трассировку, обратную к ValueError
.
Любые идеи? Спасибо!