How can I upload an image file using VueJS and Django Rest Framework?

Hello, I am currently in the process of editing a blog page using VueJS and Django Rest Framework. However, I am facing an issue when trying to upload a photo - I keep receiving an error message stating that "the sent data is not a file." Additionally, I am unable to select the current image as the default image is Null. My queries are how to create a functional photo change form and how to begin with the image already loaded in the JSON file. Thank you for any assistance provided. Please note that I have not yet set up the admin system.

VueJS

<template>
    <h1>ARTICLE</h1>
    <form @submit="onSubmit">
        <input type="text" name="title" placeholder="Title" v-model="form.title">
        <input type="text" name="desc" placeholder="Description" 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="slug" 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)

Answer №1

Take a look at the DRF settings for instructions on adding

rest_framework.parsers.FileUploadParser
. This parser is used to parse raw file upload content, where the request.data property will have a dictionary with a key 'file' that contains 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",
    ),
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating sequential numbers using jQuery

Recently, I worked on a script (credit to Chyno Deluxe) that generates a list of menu items based on what is written in the input box. However, I now have a new requirement which involves generating a sequence of numbers to be added continuously. Here is ...

Incorporating invisible surprises into a fixed menu that reveal themselves as you scroll

I am working on implementing a top navigation and a sticky sub-navigation feature. The goal is to have the sticky nav become the top nav when the user scrolls down the page, similar to the functionality on this website - The issue I'm facing is with ...

Building an Angular form that is reactive and dynamically populates fields from an array

I am currently working with Angular 9 and I am facing a challenge in implementing a component that utilizes reactive forms. Below is a snippet of my code: approval-edit.component.ts public nominationAllOf: NominationAllOf[]; public approvalEditForm: Form ...

Eliminate unneeded null and empty object data attributes within Vue.js

When sending object data to an API, I have multiple states but not all of them are required every time. Therefore, I would like to remove any properties from the object that are null or empty strings. How can I achieve this? export default { methods: { ...

Enhancing webpage design by dynamically changing borders and headers using JavaScript

I have implemented a fixed positioning for the table headers using the following code: onScroll={() => { document.querySelector('thead').style.transform = `translate(0,${this.scrollRef.scrollTop}px)`; }} However, when I scroll the ta ...

What sets the Event and EventHandler apart from each other in terms of functionality?

I am posting this question to gain clarity on the fundamental distinctions and practical applications of the Event versus EvenHandler. ...

The technique for accessing nested key-value pairs in a JSON object within an Angular application

After receiving the response from the backend, I have retrieved a nested hash map structure where one hash map is nested within another: hmap.put(l,hmaps); //hmap within hmap When returning the response to the frontend, I am using the ResponseEntity meth ...

Is there a way to retrieve the number of swipe up interactions from Instagram story insights using the graph API

Is there a way to retrieve the swipe up count displayed in Instagram insights? Since Facebook does not provide this data through their Graph API, how can I access it? I have already tried scraping without success and I am looking for a solution using eith ...

Error encountered in ASP.NET MVC application when using jQuery POST method: data is null

I am currently utilizing a PartialView and injecting it into a <div> from another PartialView to create a popup modal using the Bootstrap Modal. Although my Bootstrap Modal is displaying correctly, it is not functioning as intended. The following are ...

Error occurred in custom directive library due to unhandled TypeError

I have developed a personalized directory for tooltips and I am looking to turn it into a reusable library that can be imported and utilized in various projects. I have successfully created the library and imported it into different projects. However, upon ...

Utilize Meteor's ability to import async functions for seamless integration into method calls

Encountering an issue with this Meteor app where the error TypeError: vinXXX is not a function occurs when attempting to call an exported async function named "vinXXX" from within a method call in a sibling folder, which has been imported in the methods f ...

"Learn the trick to concealing a modal and unveiling a different one with the power of jquery

Whenever I try to open a modal, then click on a div within the modal in order to close it and open another one, I encounter an issue. The problem is that upon closing the first modal and attempting to display the second one, only the background of the seco ...

Utilizing Javascript to Open a New Tab from Drupal

I'm attempting to trigger the opening of a new tab when a specific menu link is clicked within a Drupal website. My initial approach was to incorporate JavaScript directly into the content of the page, but unfortunately this method has not been succes ...

Creating animated reactions in discord.js is a goal of mine, however, I am encountering an issue that needs to

Last year, I asked this question and received helpful answers. However, there is still a problem that I couldn't figure out. Since I am unable to comment on the previous answers, I have decided to add a new question client.on('message', mess ...

Unfortunately, we encountered an AJAX error while trying to access data from the website datatables.net. You can find

I'm currently working on adding data to a datatables.net datatable using a JSON response, following the example provided here. To achieve this, I am making use of an AJAX call to fetch a JSON response from a database. After obtaining the data, I uti ...

What is the best way to create a line graph with D3.js in order to display data that is obtained from a server-side source?

I am trying to access data from a server side link, which is as follows: The data I want to retrieve is in JSON format and looks like this: {"Id":466,"Name":"korea", "Occurren ...

"Implementing Scrollify.js to dynamically add a class to the current section

I'm attempting to dynamically add an 'active' class to the current section on a page using scrollify.js. While I can retrieve the index value, I am struggling to get the section id or class. How can I obtain the id or class of the current s ...

Troubleshooting issues with ng-options not correctly updating ng-model in AngularJS when using ajax requests

I have a question regarding my logic that I can't seem to figure out. In this Fiddle example, everything works fine without using AJAX or a timeout. However, when I try to implement the same logic with a timeout/ajax, the expected behavior does not o ...

Ways to update a nested object by utilizing the setState method

I have a situation where I need to modify the key/value pairs of an object in my state. Specifically, I need to add a key/value pair to the object with an ID of 13. Please refer to the attached photo for reference. Although I know how to use setState, I ...

How to use multiple template urls in Angular 6

Currently, I am creating a front-end using Angular 6 and facing the challenge of having components with varying html structures based on the user who is logged in. The number of templates required can range from 2 to over 20, so my preference would be to ...