我有一个models.py,如下所示,我试图在一个请求中制作多个上传文件。
以及模型中的其他字段,我将值放在后端,因此,我确切需要如何在一个请求中发送数据(文件)数组并处理文件并为每个单独的文件创建记录?
我也读了很多书,看到了很多答案,但是我认为解决方案取决于具体情况,也许是因为我没有得到答案
请问有人可以帮助我吗?
models.py
file_name = models.FileField(upload_to='docs/', null=True, blank=True)
created_by = models.ForeignKey(User, related_name='file_created_by', blank=True, null=True,on_delete=models.DO_NOTHING)
created_date = models.DateTimeField(auto_now_add=True)
serializers.py
class FileSerializer(serializers.ModelSerializer):
class Meta:
model = File
fields = '__all__'
def __init__(self, *args, **kwargs):
many = kwargs.pop('many', True)
user = kwargs['context']['request'].user
super(FileSerializer, self).__init__(many=many, *args, **kwargs)
def create(self, validated_data):
validated_data['status'] = 'in_progress'
self.context["file_name"] = self.context['request'].FILES.get("file_name")
obj = File.objects.create(**validated_data)
return obj
views.py
class FileCreateAPIView(CreateAPIView):
queryset = File.objects.all()
serializer_class = FileSerializer
permission_classes = [IsOwnerOrReadOnly]
def get_queryset(self):
return File.objects.all()
def perform_create(self, serializer):
serializer.save(created_by=self.request.user, updated_by=self.request.user)
答案 0 :(得分:1)
将file_name
模型字段的默认序列化器字段更新为serializers.ListField
,并更新序列化器中的create
方法以遍历列表以创建多个对象。
示例:
class FileSerializer(serializers.ModelSerializer):
file_name = serializers.ListField(
child=serializers.FileField(
max_length=100000, # length of the file name
allow_empty_file=False,
use_url=False
),
write_only=True
)
class Meta:
model = File
fields = ('created_by', 'file_name', )
def create(self, validated_data):
files = validated_data.pop("file_name")
obj = None
# can also use `bulk_create`, if too many files
for file in files:
obj = File.objects.create(file_name=file, **validated_data)
return obj
注意:如果将序列化程序用于列表用例,则序列化程序现在将不输出任何file_name
键。为此,您可以添加另一个字段fname
或其他内容作为serializers.SerializerMethodField
并返回文件名的值。
示例:
class TestSerializer(serializers.ModelSerializer):
test_field = serializers.SerializerMethodField()
def get_test_field(self, obj):
# since your field would be a file, so you can access `name` attribute
return obj.test_field.name
fields = ('test_field', ...rest of the fields...)