我使用 boto3 将文件上传到 S3 并将其路径保存在 FileField 中。
class SomeFile(models.Model):
file = models.FileField(upload_to='some_folder', max_length=400, blank=True, null=True)
对于上述模型,以下代码可用于创建记录。
ff = SomeFile(file='file path in S3')
ff.full_clean()
ff.save()
现在,当我使用 ModelSerializer 执行相同操作时。
class SomeFileSerializer(serializers.ModelSerializer):
class Meta:
model = SomeFile
fields = ('file')
运行下面的代码后出现此错误
rest_framework.exceptions.ValidationError: {'file': [ErrorDetail(string='提交的数据不是文件,请检查表单上的编码类型。', code='invalid')]}
serializer = SomeFileSerializer(data={'file': 'file path to S3'})
serializer.is_valid(raise_exception=True)
我需要帮助来设置序列化器以接受文件路径,但实际上没有该文件。
我确实遇到了同样的情况,在网上很难找到解决方案。
我们有两种选择来解决这个问题。
序列化器.py
from rest_framework import serializers
class SomeFileSerializer(serializers.ModelSerializer):
file = serializers.ImageField(read_only=True)
class Meta:
model = SomeFile
fields = ('file')
views.py
serializer = SomeFileSerializer(data={'file': 'file path to S3'})
serializer.is_valid(raise_exception=True)
# for put method
serializer.save(file=request.data.get('file'))
# for patch method (if partial=True in serializer)
if request.data.get('file'):
serializer.save(file=request.data.get('file'))
else:
serializer.save()
序列化器.py
from rest_framework import serializers
class SomeFileSerializer(serializers.ModelSerializer):
file = serializers.CharField(max_length=400)
class Meta:
model = SomeFile
fields = ('file')
def to_representation(self, instance):
representation = super().to_representation(instance)
if instance.file:
# update filename to response absolute url
representation['file'] = instance.file_absolute_url
return representation
模型.py
class SomeFile(models.Model):
file = models.FileField(upload_to='some_folder', max_length=400, blank=True, null=True)
@property
def file_absolute_url(self):
return self.file.url if self.file else None
虽然我因为 drf_spectaulous 的文档而选择了第二个解决方案,但第一个解决方案很容易实现。
要将通过 Django FileField 上传的文件存储在 Amazon S3 上而不是本地,您可以使用 django-storages 库以及 Django 的 FileField。以下是有关如何实现此目标的分步指南:
安装 django-storages:首先,您需要安装 django-storages 库。您可以通过 pip 来完成此操作:
pip install django-storages
配置您的 S3 凭证:在 Django 项目的设置中,配置您的 S3 凭证和存储桶名称。例如:
#settings.py
AWS_ACCESS_KEY_ID='your-access-key'
AWS_SECRET_ACCESS_KEY = 'your-secret-key'
AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'
# settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIA_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
# models.py
from django.db import models
class MyModel(models.Model):
upload = models.FileField(upload_to='uploads/')
$ python manage.py makemigrations
$ python manage.py migrate
现在,当您通过 Django 应用程序中的 FileField 上传文件时,它将直接存储在 Amazon S3 上,而不是本地存储在您的服务器上。