この記事の概要
reactとdjango-rest-frameworkを用いた画像アップロード機能について記載する。
django×Reactの画像アップロード機能の実装方法
Django(django-rest-framework)の作成【バックエンド】
configの設定(画像の保存先)
config/settings.py
import os #追加
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') #追加
MEDIA_URL = '/media/' #追加
config/urls.py
from django.conf import settings # 追加
from django.contrib.staticfiles.urls import static # 追加
from django.contrib.staticfiles.urls import staticfiles_urlpatterns # 追加
urlpatterns += staticfiles_urlpatterns() # 追加
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # 追加
modelsの作成
api/models.py
class Food(models.Model):
img = models.ImageField(verbose_name='画像', upload_to='images/food/', null=True, blank=True) # 追加
serializersの作成
api/serializers.py
# 特に変更なし
viewsの作成
api/views.py
# 特に変更なし
urlsの作成
api/urls.py
# 特に変更なし
Reactの作成【フロントエンド】
App.js
※特に変更なし
FoodList.js
import { useState, useEffect } from 'react';
import axios from 'axios';
const FoodList = () => {
const initState = {
id: '',
name: '',
content: '',
}
// 一覧表示部分
const [list, setList] = useState(initState);
const [loading, setLoading] = useState(true);
useEffect(() => {
axios.get(`http://localhost:8000/api/food/`)
.then((res) => {
setList(res.data);
setLoading(false);
})
.catch((err) => {
throw new Error(err)
})
.finally(() => {
})
}, [])
// 画像アップロード部分
const [img, setImg] = useState(new Blob());
const handleImageInputChange = (e) => {
const files = e.target.files;
console.log(files)
if (!files) return;
setImg(...files)
}
const handleUploadClick = () => {
let data = new FormData();
data.append('img', img);
data.append('name', list[4].name)
console.log(list[4].name)
console.log(img)
axios.put('http://localhost:8000/api/food/5/', data)
.then((res) => console.log(res.data))
.catch((err) => console.log(err))
}
return (
<>
<h1>foodlist</h1>
{
loading?
<h1>...Loading</h1>
:
<>
{list.map(f =>
<div key={f.id}>
<p key={f.id}>{f.name}</p>
<img src={f.img} />
</div>
)}
</>
}
<h1>foodcreate</h1>
<input type='file' onChange={(e) => {handleImageInputChange(e)}}/>
<button onClick={() => {handleUploadClick()}}>アップロード</button>
<div
style={{
position: "relative",
width: "40%",
}}
>
<img
src={URL.createObjectURL(img)}
style={{
width: "100%"
}}
/>
</div>
</>
)
}
export default FoodList;