【问题标题】:How to update an Input file (image) in vueJS and Django rest?如何在 vueJS 和 Django rest 中更新输入文件(图像)?
【发布时间】:2021-06-26 04:15:52
【问题描述】:

早上好,我目前正在编辑使用 VueJS 和 Django Rest Framework 的博客。当我尝试上传照片时,我收到一个错误“发送的数据不是文件”,并且我目前无法选择当前图片(默认图片为 Null)。问题是如何制作一个工作变化的照片表格,以及如何从已经在 J​​Son 文件中加载的图像开始。感谢所有的答案。现在我还没有做管理员系统。

VueJS

<template>
    <h1>ARTICOLO</h1>
    <form @submit="onSubmit">
        <input type="text" name="title" placeholder="Titolo" v-model="form.title">
        <input type="text" name="desc" placeholder="Descrizione" v-model="form.desc">
        <input type="text" name="category" v-model="form.category">
        <input type="file" name="image" @change="EditImage" >
        <input type="text" name="author" v-model="form.author">
        <input type="text" name="author" v-model="form.slug">
        <textarea name="text" v-model="form.text"></textarea>

        <button type="submit" @click= "editPost">Edit</button>
    </form>
</template>
<script>
import axios from 'axios';
import { getAPI } from '../api'
export default {
    data () {
        return{
            Postslug: this.$route.params.Postslug,
            form: {
                title:"",
                desc:"",
                text:"",
                category:"",
                date:"",
                author:"",
                image:"",
                slug:"",
            },
            selectedFile: null
        }
    },
    methods: {
        // Form method
        onSubmit(event){
            event.preventDefault();     
            axios.put(`http://127.0.0.1:8000/blog/api/edit/${this.Postslug}`, this.form).then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
              alert('Ok')
            })
            .catch(err => {
              console.log(err)
            })
        },
        EditImage(event){
            this.selectedFile = event.target.files[0]
            console.log(event);
        },
        editPost(){
            const fd = FormData();
            fd.append('image', this.selectedFile, this.selectedFile.name)
            axios.put(`http://127.0.0.1:8000/blog/api/edit/${this.Postslug}`, fd)
            .then(response =>{
                console.log(response);
            })
        }
        
    },
    created() {
        getAPI.get(`blog/api/edit/${this.Postslug}`)
            .then(response => {
              this.form.title = response.data.title
              this.form.desc = response.data.desc
              this.form.text = response.data.text
              this.form.date = response.data.date
              this.form.image = response.data.image
              this.form.category = response.data.category
              this.form.author = response.data.author
              this.form.slug = response.data.slug
            })
            .catch(err => {
              console.log(err)
            })
        },
    name: 'AdminEditArticle',
}
</script>
<style lang="sass" scoped>
</style>  

Axios 获取

import axios from 'axios'
const getAPI = axios.create({
    baseURL: 'http://127.0.0.1:8000',
    timeout: 1000,
})
export { getAPI }

Serializers.py

from rest_framework.fields import ReadOnlyField
from rest_framework.serializers import ModelSerializer, SerializerMethodField
from Blog.models import *

class PostListSerializer(ModelSerializer):
    author = SerializerMethodField()
    category = SerializerMethodField()
    class Meta:
        model = Post
        fields = ('id', 'title', 'author', 'category', 'image', 'desc', 'text', 'slug', 'date')

    def get_author(self, obj):
        return str(obj.author.username)
    
    def get_category(self, obj):
        return str(obj.category.name)


class PostDetailSerializer(ModelSerializer):
    class Meta:
        model = Post
        fields = ('id', 'title', 'author', 'category', 'image', 'desc', 'text', 'slug', 'date')
        def save(self, *args, **kwargs):
            if self.instance.image:
                self.instance.image.delete()
            return super().save(*args, **kwargs)

Models.py

class Post(models.Model): 
    title = models.CharField(max_length=299)
    author = models.ForeignKey(User,default=ANONYMOUS_USER_ID, on_delete=models.CASCADE)
    category = models.ForeignKey(Category,default=ANONYMOUS_USER_ID, on_delete=models.CASCADE)
    image = models.ImageField(blank=True)
    desc = models.TextField()
    text = RichTextField(blank = True, null = True )
    date = models.DateTimeField(auto_now=False, auto_now_add=True)
    slug = models.SlugField(null = True, blank = True, unique=True)

    class Meta: # Order post by date
        ordering = ['-date',]

    def __str__(self): # Display title 
        return self.title

    def get_absolute_url(self): # #TODO da cambiare
        return reverse("listpost")

    def save(self, *args, **kwargs): # Auto Slug Field
        self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

【问题讨论】:

    标签: javascript django vue.js django-rest-framework axios


    【解决方案1】:

    选中drf settings 以添加rest_framework.parsers.FileUploadParser。解析原始文件上传内容。 request.data 属性将是一个包含上传文件的单键“文件”的字典。

    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": (
            "rest_framework.authentication.SessionAuthentication",
            "rest_framework.authentication.BasicAuthentication",
        ),
        "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
        "DEFAULT_FILTER_BACKENDS": [
            "django_filters.rest_framework.DjangoFilterBackend",
            "rest_framework.filters.OrderingFilter",
        ],
        "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
        "DEFAULT_METADATA_CLASS": "rest_framework.metadata.SimpleMetadata",
        "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.openapi.AutoSchema",
        "PAGE_SIZE": 50,
        "MAX_LIMIT": 50,
        "TEST_REQUEST_DEFAULT_FORMAT": "json",
        "DEFAULT_RENDERER_CLASSES": (
            "rest_framework.renderers.JSONRenderer",
            "rest_framework.renderers.BrowsableAPIRenderer",
        ),
        "DEFAULT_PARSER_CLASSES": (
            "rest_framework.parsers.JSONParser",
            "rest_framework.parsers.FormParser",
            "rest_framework.parsers.MultiPartParser",
            "rest_framework.parsers.FileUploadParser",
        ),
    }
    

    【讨论】:

    • 请提供网址和查看方式
    • 查看浏览器开发者控制台天气this.form在发送put请求前有图片
    • 默认没有输入图片
    • 您将文件添加到selectedFile: null,但您的put 发送form。您应该将文件放入适当的表单域以发送它。编辑评论
    • editPost 重复 onSubmit。它们应该合并,你应该只保留一个
    猜你喜欢
    • 2018-05-30
    • 2019-08-28
    • 2019-01-19
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    相关资源
    最近更新 更多