0

I am trying to upload image from React frontend and deliver this image object to Django, Python backend, with Imgur API. (imgurpython)

My goal is to upload the image to Imgur in Python backend and gets image url from Imgur, finally I will return this url back to React frontend side to use.

But I have some problem and confused it how to get this Image File in Django views with request.

Here is my frontend page.

enter image description here

And there are my codes

frontend/Screen

import React, {useState,useEffect} from 'react'
import { Link } from 'react-router-dom'
import { useDispatch, useSelector} from 'react-redux'
import { Row, Col, ListGroup, Image, Form, Button, Card } from 'react-bootstrap'
import Message from '../components/Message'
import { uploadImage } from '../actions/caseActions'

function CaseScreen({ match, location, history}) {
    const dispatch = useDispatch()
    const [image, setImage] = useState(null)

    const handleInputChange =(event) =>{

        event.preventDefault();
        console.log(event)
        console.log(event.target.files[0])
        setImage({
          image: event.target.files[0]
        });
    }
    const uploadImgurImage = (event) => {
        event.preventDefault();
        let data = new FormData(); 
     
        data.append("image", image); 
  
        dispatch(uploadImage(data)) // send to actions
        
        
    }

    
    return (
        <Row>
            <Col md={8}>
                <Card>個案頁</Card>
                

                    <form onSubmit={uploadImgurImage}>
                    <input type="file" name="image" onChange={handleInputChange}/>
                    <button>Submit</button>
                    </form>  
            </Col>
                    
        </Row>
    )
}
export default CaseScreen

frontend/uploadActions

    import axios from 'axios'
    import {
        UPLOAD_IMAGE_REQUEST ,
        UPLOAD_IMAGE_SUCCESS ,
        UPLOAD_IMAGE_FAIL,
       } from '../constants/caseConstants'
    export const uploadImage = (file) => async (dispatch, getState) => {
        
        try {
           
    
            dispatch({
                type: UPLOAD_IMAGE_REQUEST
            })
    
            console.log(file)
            const {
                userLogin: { userInfo },
            } = getState()
    
            const config = {
                headers: {
                    'Content-type': 'application/json',
                    Authorization: `Bearer ${userInfo.access}`
                }
            }
    
            const { data } = await axios.post(
                `/api/imgur/upload/`,
                file,
                config
            )
    
            dispatch({
                type:UPLOAD_IMAGE_SUCCESS,
                payload:data
                
            })
    
           
    
        } catch (error) {
            dispatch({
                type: UPLOAD_IMAGE_FAIL,
                payload: error.response && error.response.data.detail
                    ? error.response.data.detail
                    : error.message,
            })
        }
    }

backend/urls

path('api/imgur/',include('base.urls.imgur_urls')),

backend/urls/imgur_urls

path('upload/', views.upload_image, name="upload_image"),

backend/views (url:/api/imgur/upload/)

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response

from django.contrib.auth.models import User

from rest_framework import status

from datetime import datetime
import configparser
import base.config as env
import os

from imgurpython import  ImgurClient



@api_view(['POST'])
def upload_image(request):
    data = request.data
    
    album = env.IMGUR_ALBUM
    
    image_path=data['image']

    config = configparser.ConfigParser()
    path = '/'.join((os.path.abspath(__file__).replace('\\', '/')).split('/')[:-1])
    config.read(os.path.join(path, 'auth.ini'))
    
    
    client_id = config['credentials']['client_id']
    client_secret = config['credentials']['client_secret']
    refresh_token = config['credentials']['refresh_token']
    access_token = config['credentials']['access_token']
    client = ImgurClient(client_id,client_secret, refresh_token)
    client.set_user_auth(access_token, refresh_token)   

    if client:
        config={
            'album':album,
            'name':'Ezra',
            'title':'Test',
            'description': 'Test {0}'.format(datetime.now())
        }

        print("Uploading image")
        image = client.upload_from_path(image_path,config=config,anon=False)
        print(image['link'])
        print("Done")
        return image

    else:return "Error"

I can execute this upload function when I put image in the same folder in backend. But I want to get image file from frontend, the image seems not be delivered in parameter "request". So image = client.upload_from_path(image_path,config=config,anon=False) doesn't work.

I want to know how to fix this problem to let my backend function upload_image get File Object to upload. Thank you.

Ezra Lin
  • 87
  • 9
  • 1
    You can upload your image to Imgur from React, get the link and save it to django backend. There is a library fo React: https://github.com/MiguhRuiz/react-imgur-upload – Giancarlo Ventura Aug 18 '21 at 12:46
  • 2
    You need to use `multipart/form-data` as your content type to send files. See https://stackoverflow.com/a/43014086/548562 – Iain Shelvington Aug 18 '21 at 12:48
  • 1
    You can upload the img to Django too and send it to imgur https://github.com/preetamherald/django-imgur – Giancarlo Ventura Aug 18 '21 at 12:49
  • @IainShelvington Thank you. I met another problem that my backend show that `FileNotFoundError: [Errno 2] No such file or directory: '[object Object]'` when I try to use `client.upload_from_path(image_path,config=config,anon=False)` to upload. How can I set this image_path without backend directory? Thanks a lot. – Ezra Lin Aug 19 '21 at 02:15
  • @GiancarloVentura Thanks for your two ways to upload to Imgur. I'll try them too later. Both of them seem great ways too. Thanks again. The first way is more efficient than now and the second one is another way that I never thought out. – Ezra Lin Aug 19 '21 at 02:20

0 Answers0