Загрузка нескольких файлов моделей с использованием DRF - PullRequest
0 голосов
/ 24 октября 2019

У меня model.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)

1 Ответ

1 голос
/ 24 октября 2019

Обновите 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...)
...