0

Good morning, I'm currently working to the edit page for a blog using VueJS and Django Rest Framework. When I try to upload a photo I receive an error "the sended datas are not a file" and I' not currently able to select the current image (the default image is Null). The questions are how to make a working changing photo form and how to start with the image already charged in the JSon file. Thanks for all answers. Right now I have not made the admin system.

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 get

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)

1 Answer 1

1

Check drf settings to add rest_framework.parsers.FileUploadParser. Parses raw file upload content. The request.data property will be a dictionary with a single key 'file' containing the uploaded file.

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",
    ),
}
Sign up to request clarification or add additional context in comments.

8 Comments

Provide url and view, pls
Check in the browser developer console weather this.form has an image before sending put request
It has not an input image by defalut
You add file to selectedFile: null but your put sends form. You should put file to the appropriate form field to send it. Edited comment
editPost duplicates onSubmit. They should be merged and you should keep only one
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.