Загрузка нескольких изображений с помощью Django Rest Framework и Ajax - PullRequest
0 голосов
/ 01 мая 2020

Я создаю CreateAPIView с Django Rest Framework и вызываю его с ajax. Я хочу загрузить несколько изображений с сообщением, но могу загрузить только 1 изображение.

Это моя модель:

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts',
                             on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now=True)
    message = models.TextField(blank=True)
    message_html = models.TextField(editable=False)
    group = models.ForeignKey(
        Group, related_name='posts', null=True, blank=True, on_delete=models.CASCADE)
    liked = models.ManyToManyField(
        settings.AUTH_USER_MODEL, blank=True, related_name='post_liked')
    updated = models.DateTimeField(auto_now=True, blank=True)
    destination = models.ForeignKey(
        Destination, on_delete=models.CASCADE, blank=True, null=True)
    type = models.CharField(choices=CATEGORY, max_length=100, default='Public')

    objects = PostManager()

    def __str__(self):
        return self.user.username
    ....

class PostImage(models.Model):
    post = models.ForeignKey(
        Post, on_delete=models.CASCADE, default=None, related_name='post_images')
    image = models.FileField(upload_to='post-files', blank=True)

    def __str__(self):
        return self.post.message

Это мой сериализатор:

class PostImageModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = PostImage
        fields = '__all__'


class PostModelSerializer(serializers.ModelSerializer):
    def __init__(self, *args, **kwargs):
        file_fields = kwargs.pop('file_fields', None)
        super().__init__(*args, **kwargs)
        if file_fields:
            field_update_dict = {field: serializers.FileField(
                required=False, write_only=True) for field in file_fields}
            self.fields.update(**field_update_dict)

    def create(self, validated_data):
        validated_data_copy = validated_data.copy()
        validated_files = []
        for key, value in validated_data_copy.items():
            if isinstance(value, InMemoryUploadedFile):
                validated_files.append(value)
                validated_data.pop(key)
        post_instance = super().create(validated_data)
        print(validated_files)
        for file in validated_files:
            PostImage.objects.create(
                post=post_instance, image=file)
        return post_instance

    user = UserDisplaySerializer(read_only=True)
    post_images = PostImageModelSerializer(many=True, read_only=True)
    timesince = serializers.SerializerMethodField()
    destination = DestinationDisplaySerializer(read_only=True)
    did_like = serializers.SerializerMethodField()
    liked = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = ['id', 'user', 'message', 'type',
                  'destination', 'timesince', 'did_like', 'liked', 'post_images']
    ....

Это мой API:


class PostsCreateApiView(generics.CreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostModelSerializer

    def create(self, request, *args, **kwargs):
        file_fields = list(request.FILES.keys())
        serializer = self.get_serializer(
            data=request.data, file_fields=file_fields)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

и мой ajax вызов:

 $('#postForm').on('submit', function (e) {
            e.preventDefault();
            var form = $(this);
            var formdata = false;
            if (window.FormData) {
                formdata = new FormData(form[0]);
            }
            if (charsCurrent > 0 && charsCurrent <= charsTotal) {
                $.ajax({
                    url: "/api/posts/create/",
                    data: formdata ? formdata : form.serialize(),
                    method: "POST",
                    processData: false,
                    contentType: false,
                    success: function (data) {
                        fetchPosts();
                        form.find("input[type=text], textarea").val("");
                        $('#inputLaunchToPOST').modal('hide');
                        attachPost(data, true);
                        // updateHashLinks();
                    },
                    error: function (data) {
                        console.log("error");
                        console.log(data.statusText);
                        console.log(data.status);
                    },
                });
            }
        });

Этот код получает только одно изображение, в то время как я проверяю его на 2 или 3 изображения для один пост. Я думаю, что-то с «InMemoryUploadedFile» я использовал в своем сериализаторе.

...