Django Rest Framework (DRF) - Загрузка файлов

01 Сен 2022 , 56

В этой статье рассмотрим как можно загружать файлы с помощью Django Rest Framework.

Рассмотрим простой случай. У нас есть модель Post , у которого есть поле preview , куда нужно загружать изображения 

Файл blog/models.py


from django.db import models


class Post(models.Model):
    name = models.CharField(max_length=255)
    preview = models.ImageField(upload_to='posts')
    content = models.TextField()
    
    def __str__(self):
        return self.name
    
    class Meta:
        verbose_name = 'Пост'
        verbose_name_plural = 'Посты'



Создаем сериализатор blog/serializers.py


from rest_framework.serializers import ModelSerializer
from blog.models import Post


class PostSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = ('name', 'preview', 'content')

Создаем стандартный modelvewset blog/views.py


from rest_framework import viewsets
from blog.models import Post
from blog.serializers import PostSerializer


class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer


Создаем blog/urls.py


from django.urls import include, path

from rest_framework.routers import SimpleRouter
from blog.views import PostViewSet


router = SimpleRouter()
router.register(r'posts', PostViewSet, basename='posts')

urlpatterns = [
    path('', include(router.urls)),
]


И в вашем основном файле urls.py добавьте следующие строки.


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/blog/', include(('blog.urls', 'blog'), namespace='blog')),
]


Попробуем через стандартную интерфейс создать новый пост.

При запросе используется значение Content-Type равной 'multipart/form-data'.



С помощью curl запрос на добавление нового поста делается следующим образом


curl -X POST -F "name=Второй запрос" -F "content=текст второго поста" -F preview=@dune.png http://localhost:8000/api/blog/posts/

Пост создался и файл загрузился. Магия. Все работает и мы даже не знаем как. Давайте попытаемся разобраться.

Когда обрабатывается запрос , то при доступе к request.data DRF проверит заголовок Content-Type во входящем запросе и определит, какой синтаксический анализатор(Парсер) использовать для анализа содержимого запроса. Так как в нашем случае при отправке файлов Content-Type равно multipart/form-data , то DRF для парсинга входящих данных будет использовать парсер MultiPartParser. Это происходит отчасти и из-за того , что данный парсер по умолчанию указан в DRF

По умолчанию DRF определяет следующие парсеры:


DEFAULTS = {
    'DEFAULT_PARSER_CLASSES': [
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser'
    ],

Также MultiPartParser использует обработчики для сохранения отправленных файлов(По умолчанию , используются стандартные загрузчики файлов Django)

comments powered by Disqus

Подписка

Подпишитесь на наш список рассылки, чтобы получать обновления из блога

Рубрики

Теги