UnicodeDecodeError - Django Upload file
Я использую Django Rest Framework, и с помощью простой формы на фронтенде я загружаю некоторые данные и вложения в модель в Django.
Я храню файлы на AWS S3, и я использую Django S3 Storage.
Когда я загружаю файл, я получаю UnicodeDecodeError следующим образом. (Трассировку смотрите внизу)
Моя модель файла
class JourAttachment(models.Model):
jourreport = models.ForeignKey(JourReport,related_name="jourattachments", on_delete=models.CASCADE)
file = models.FileField(null=False)
Вид
class JourReportListView(APIView):
serializer_class = JourReportListSerializer
permission_classes = (IsAuthenticated, )
parser_classes = (MultiPartParser,)
def post(self,request,*args, **kwargs):
user_making_request = request.user
if not user_is_admin(user_making_request):
return UserNotAdminResponse()
attachments = request.FILES.getlist('attachment', None)
serializer = JourReportCreateUpdateSerializer(data=request.data,partial=True,context={'attachments': attachments})
valid = serializer.is_valid(raise_exception=True)
if valid:
report = serializer.save()
status_code = status.HTTP_201_CREATED
#send_mail_with_jourreport(report)
return SuccessfulResponse(data=request.data, message="Jour report successfully registered!" ,status_code=status_code)
return ErrorResponse()
Сериализатор
class JourReportCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = JourReport
fields = ('apartment_number', 'address', 'tenant_name','tenant_phone', 'debit_tenant','worker','total_hours', 'additional_workers','defect_description','actions_made','actions_to_be_made')
def create(self, validated_data):
users = []
attachments = self.context['attachments']
if "additional_workers" in validated_data:
users = [w.id for w in validated_data["additional_workers"]]
del validated_data["additional_workers"]
report = JourReport.objects.create(**validated_data)
for a in attachments:
JourAttachment.objects.create(file=a,jourreport=report) # Add attachments to instance
if(len(users) > 0):
report.additional_workers.add(*users)
return report
Модель добавляется правильно, и все файлы сохраняются, но в любом случае я получаю ответ 500 с UnicodeDecodeError Trace
Traceback (most recent call last):
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/rest_framework/renderers.py", line 100, in render
ret = json.dumps(
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/rest_framework/utils/json.py", line 25, in dumps
return json.dumps(*args, **kwargs)
File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/__init__.py", line 234, in dumps
return cls(
File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/opt/homebrew/Cellar/python@3.9/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/jakobkarlstrand/Documents/Programming/weknowit/HaningeBostader/backend/venv/lib/python3.9/site-packages/rest_framework/utils/encoders.py", line 50, in default
return obj.decode()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa2 in position 50: invalid start byte
У меня также есть пользовательский обработчик хранения S3:
class CustomS3Storage(S3Storage,ABC):
def _save(self, name, content):
"""
We create a clone of the content file as when this is passed to boto3 it wrongly closes
the file upon upload where as the storage backend expects it to still be open
"""
# Seek our content back to the start
content.seek(0, os.SEEK_SET)
# Create a temporary file that will write to disk after a specified size
content_autoclose = self.new_temporary_file()
# Write our original content into our copy that will be closed by boto3
content_autoclose.write(content.read().strip())
content_autoclose.file = content.file
# Upload the object which will auto close the content_autoclose instance
result = super()._save(strip_non_ascii(name), content_autoclose)
# Cleanup if this is fixed upstream our duplicate should always close
if not content_autoclose.closed:
content_autoclose.close()
return result
Проблема была в ответе:
return SuccessfulResponse(data=request.data,message="Jour report successfully registered!" ,status_code=status_code)
Я возвращаю данные запроса, включая файлы, что приводит к ошибке. Удалите его или сначала выполните сериализацию, чтобы избавиться от ошибки