Неправильный путь вместо фактического файла сохраняется в бэкенд в Django

Мы действительно боремся с этим

У меня есть Vue front end с HTML формой

        <form id="postForm" method="POST" action="">

            <div class="mediaButtons horizontal mb10">
                <div class="mediaButton">
                    <input
                        type="file"
                        name=""
                        id="postImages"
                        accept="image/jpg, image/png, image/jpeg, image/tiff, image/webp, image/bmp, image/svg"
                        @change="handleImages"
                        multiple
                        maxFileSize="50000"
                    />
                    <div class="buttonImage">
                        <img class="buttonImg" src="../assets/img/pic.png" />
                    </div>
                </div>
            </div>
            <fieldset class="postButtons mt20" v-if="catChosen">
                <button class="topBtn" type="button" name="addPost" @click="submitPost">
                    Post
                </button>
                <button
                    class="canBtn"
                    type="button"
                    name="addPost"
                    @click="store.hideAddaPost"
                >
                    Cancel
                </button>
            </fieldset>
        </form>

Функция для обработки изображений и их отображения следующая:

import { ref } from "vue";

const fields = ref({
    previews: [],
    images: [],
});

function handleImages(event) {
    var input = event.target;
    var count = input.files.length;
    function isFileImage(file) {
        return file && file["type"].split("/")[0] === "image";
    }
    if (count > 8) {
        return store.messages.push("Max 8 images per post please");
    }
    for (const file of input.files) {
        if (isFileImage(file)) {
        } else {
            return store.messages.push("Only image files are allowed");
        }
    }
    var index = 0;
    while (count--) {
        var reader = new FileReader();
        reader.onload = (e) => {
            fields.value.previews.push(e.target.result);
        };
        fields.value.images.push(input.files[index]);
        reader.readAsDataURL(input.files[index]);

        index++;
    }
}

Я отправляю данные на бэкэнд с помощью этой функции:

function submitPost() {
    let uploaded_images = []
    fields.value.images.forEach((val) => uploaded_images.push(val))
    const fieldsData = {
        "category": selectedCat.value,
        "body": fields.value.body,
        "can_view": fields.value.audience,
        "can_comment": fields.value.cancomment,
        "published": true,
        "video": fields.value.video,
        "user": store.userId,
        "uploaded_images": uploaded_images
    };
    axios
        .post("api/v1/posts/create/", fieldsData, {
            headers: {
                "Content-Type": "multipart/form-data",
                "X-CSRFToken": "{{csrf-token}}",
            },
        })
        .then((response) => {
            if (response.status == 201) {
                store.messages.push("Post created successfully");
            }
        })
        .catch((error) => {
            store.messages.push(error.message);
        });
}

после отправки данных и файлов я отправляю их на бэкенд фреймворка Django Rest со всем следующим:

views.py

class PostViewSet(viewsets.ModelViewSet):
    parser_classes = [MultiPartParser, FormParser]
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = [permissions.IsAuthenticated]
    def get_serializer_context(self):
        return {'request': self.request}

serializers.py

class PostImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PostImage
        fields = ["id", "image", "post"]
        extra_kwargs = {
            "post": {"required": True},
        }


class PostSerializer(serializers.ModelSerializer):
    images = PostImageSerializer(many=True, read_only=True, required=False)
    uploaded_images = serializers.ListField(
        required=False,
        child=serializers.FileField(
            allow_empty_file=False, 
        ),
        write_only=True,
    )

    class Meta:
        model = Post
        fields = [
            "id",
            "category",
            "body",
            "images",
            "uploaded_images",
            "video",
            "can_view",
            "can_comment",
            "user",
            "published",
            "pinned",
            "created_at",
            "updated_at",
        ]

    def create(self, validated_data):
        request = self.context.get("request")
        new_post = Post.objects.create(**validated_data)
        images = request.FILES
        if images:
            try:
                for image in images.getlist('uploaded_images'):
                    PostImage.objects.create(image=image, post=new_post)
            except:
                PostImage.objects.create(post=new_post)
            return new_post

и models.py

def user_directory_path(instance, filename):
    return 'posts/user_{0}/{1}'.format(instance.user.id, filename)

def post_directory_path(instance, filename):
    return 'posts/post_{0}/{1}'.format(instance.post.id, filename)

class Post(models.Model):

    EV = "Everybody"
    FO = "Followers"
    FR = "Friends"
    AUDIENCE = [
        (EV, "Everybody"),
        (FO, "Followers"),
        (FR, "Friends"),
    ]
    category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default=1)
    slug = AutoSlugField(populate_from=["category", "created_at", "user"])
    body = models.TextField("content", blank=True, null=True, max_length=5000)
    video = models.FileField(
        upload_to=user_directory_path, null=True, blank=True 
    )
    can_view = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
    can_comment = models.CharField(max_length=10, choices=AUDIENCE, default=EV)
    user = models.ForeignKey(
        User, on_delete=models.CASCADE, verbose_name="author")
    published = models.BooleanField(default=False)
    pinned = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = "post"
        verbose_name_plural = "posts"
        db_table = "posts"
        ordering = ["created_at"]

    def __str__(self):
        return self.body[0:30]

    def get_absolute_url(self):
        return self.slug

class PostImage(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='images')
    image = models.FileField(upload_to="posts/images", default='posts/default.png', null=True)

    class Meta:
        db_table = "post_images"
        ordering = ["post"]

Представленные данные выглядят следующим образом:

-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="category"

1
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="body"

post1
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="can_view"

Everybody
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="can_comment"

Everybody
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="published"

true
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="user"

1
-----------------------------153586592122438730432684753649
Content-Disposition: form-data; name="uploaded_images.0"; filename="tumblr_42e2ad7e187aaa1b4c6f4f7e698d03f2_c9a2b230_640.jpg"
Content-Type: image/jpeg

ÿØÿà

После отправки данных создается пост и количество PostImages, равное количеству загруженных мною изображений.

Проблема в том, что когда я пытаюсь посмотреть на одно из изображений, я получаю ошибку:

backend/storage/uploaded_images.2” does not exist

Почему в данных, которые я отправляю обратно, имя файла выглядит как "uploaded_images.0", "uploaded_images.1" и так далее, а не "uploaded_images[0]"?

Почему файлы не сохраняются по пути, который я указал в модели для поля?

Полезная нагрузка запроса явно представляет собой данные, которые не закодированы, это правильный способ отправки данных?

Вернуться на верх