Skip to content

Instantly share code, notes, and snippets.

@jsatt
Created August 26, 2020 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsatt/2773c0618603e1d6411db2eed7120021 to your computer and use it in GitHub Desktop.
Save jsatt/2773c0618603e1d6411db2eed7120021 to your computer and use it in GitHub Desktop.
Django view to capture file from multipart or body POST
from io import BytesIO
from django.conf import settings
from django.core.files.uploadedfile import InMemoryUploadedFile
from django.core.files.uploadhandler import FileUploadHandler
from rest_framework.parsers import DataAndFiles, FileUploadParser
class BodyUploadHandler(FileUploadHandler):
def new_file(self, *args, **kwargs):
super().new_file(*args, **kwargs)
self.file = BytesIO()
def receive_data_chunk(self, raw_data, start):
self.file.write(raw_data)
def file_complete(self, file_size):
self.file.seek(0)
if not file_size:
file_size = len(self.file.read())
self.file.seek(0)
return InMemoryUploadedFile(
file=self.file,
field_name=None,
name=self.file_name,
content_type=self.content_type,
size=file_size,
charset=self.charset,
content_type_extra=self.content_type_extra
)
class BodyFileParser(FileUploadParser):
media_type = '*/*'
def parse(self, stream, media_type=None, parser_context=None):
parser_context = parser_context or {}
request = parser_context['request']
encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
meta = request.META
filename = self.get_filename(stream, media_type, parser_context) or 'body'
content_type = meta.get('HTTP_CONTENT_TYPE',
meta.get('CONTENT_TYPE', ''))
try:
content_length = int(meta.get('HTTP_CONTENT_LENGTH',
meta.get('CONTENT_LENGTH', 0)))
except (ValueError, TypeError):
content_length = None
handler = BodyUploadHandler()
handler.new_file(None, filename, content_type, content_length, encoding)
handler.receive_data_chunk(stream.read(), None)
file_obj = handler.file_complete(None)
return DataAndFiles({}, {'file': file_obj})
from django.http import HttpResponse
from rest_framework.parsers import MultiPartParser
from rest_framework.views import APIView
from .parsers import BodyFileParser
class EligibilityFileView(APIView):
parser_classes = (MultiPartParser, BodyFileParser)
def post(self, request, *args, **kwargs):
content = request.FILES.get('file')
if not content:
return HttpResponse('No content provided', status=400)
# do stuff
return HttpResponse('File accepted!')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment