使用Vue.js和Django REST Framework来实现图像的注册和显示处理
总结
使用Vue.js和Django REST Framework来注册和展示图片。
GitHub链接 (GitHub
环境
macOS Monterey
Chip Apple M1 Max
Python 3.10.3
Django 4.1.4
Django REST Framework 3.14.0
vue-cli 5.0.1
Vue.js 3.2.13
步骤
虚拟环境建设
我将建立一个虚拟环境。
% python -m venv venv
激活。
% source venv/bin/activate
建立Django环境
安装 Django、djangorestframework 和 Pillow。
(venv)% pip install Django==4.1.4 djangorestframework==3.14.0 Pillow==9.3.0
生成django项目。
(venv)% django-admin start project project .
让我们启动开发服务器,然后在浏览器中打开http://127.0.0.1:8000,确认Django的默认页面是否显示出来。
(venv)% python manage.py runserver
实现后端
生成一个Django应用程序。
(venv)% python manage.py startapp app
修改项目/ settings.py的部分内容。
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # 追加
'app' # 追加
]
...
# 以下を追記
MEDIA_URL = '/media/' # 画像ファイルを参照するためのURL
MEDIA_ROOT = BASE_DIR / "media" # 画像保存先ディレクトリ
# 信頼できる発信元リストに、Vueのオリジンを追加
CSRF_TRUSTED_ORIGINS = ['http://localhost:8080']
在app/models.py中定义一个Image模型。
from django.db import models
class Image(models.Model):
image = models.ImageField(
verbose_name="画像",
blank=True,
null=True
)
class Meta:
db_table = "image"
在app/views.py文件中定义视图。
Vue.js 的部分将在稍后实施。
from rest_framework import viewsets, status
from rest_framework.response import Response
from .models import Image
from .serializers import ImageSerializer
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer
创建app/serializers.py文件,并定义ImageSerializer。
from rest_framework import serializers
from .models import Image
class ImageSerializer(serializers.ModelSerializer):
class Meta:
model = Image
fields = "__all__"
编辑project/urls.py。
from django.contrib import admin
from django.conf import settings
from django.urls import path, include
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('app.urls')) # appのurls.pyを指定
]
if settings.DEBUG:
# 画像表示用
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
我会创建一个名为 app/urls.py 的文件。
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from app.views import ImageViewSet
# ImageViewSetを設定
router = DefaultRouter()
router.register(r'image', ImageViewSet)
urlpatterns = [
path('', include(router.urls)),
]
我要进行迁移。
% python manage.py makemigrations
% python manage.py migrate
启动开发服务器,并打开http://127.0.0.1:8000/api/v1/image。



创建Vue.js项目
将此项目生成为Vue项目。
% vue create frontend
选择Vue3。
Vue CLI v5.0.1
┌─────────────────────────────────────────┐
│ │
│ New version available 5.0.1 → 5.0.8 │
│ │
└─────────────────────────────────────────┘
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
Manually select features
如果消息显示出来,就可以了。
Vue CLI v5.0.1
✨ Creating project in /Users/ryosukemaeda/Programming/Issues/django-vue-env/frontend.
⚙️ Installing CLI plugins. This might take a while...
added 848 packages in 12s
? Invoking generators...
? Installing additional dependencies...
added 96 packages in 3s
⚓ Running completion hooks...
? Generating README.md...
? Successfully created project frontend.
? Get started with the following commands:
$ cd frontend
$ npm run serve
启动开发服务器。
% cd frontend
frontend% npm run serve
只要显示Vue.js的默认页面就可以了。

前端实现
为了执行API,安装axios。
frontend% npm install axios
我要创建frontend/src/common/api.service.js,并进行以下配置。
import axios from "axios";
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.withCredentials = true;
export { axios };
我将创建frontend/src/components/RegisterImage.vue。
<template>
<div>
<form @submit.prevent="onSubmit">
<div>画像</div>
<div>
<input
type="file"
name=""
id="img-upload"
ref="file"
multiple="multiple"
@change="uploadFile"
@click="
(e) => {
e.target.value = '';
}
"
/>
</div>
<button>登録</button>
</form>
<!-- プレビュー表示 -->
<img :src="imgUrl" />
</div>
</template>
<script>
import { axios } from "@/common/api.service.js";
export default {
data() {
return {
imgData: null,
imgUrl: null,
};
},
methods: {
uploadFile() {
this.imgData = this.$refs.file.files[0];
if (!this.imgData) {
return;
}
},
async onSubmit() {
const formData = new FormData();
formData.append("imageData", this.imgData);
console.log(this.imgData);
try {
const endpoint = "/api/v1/image/";
const response = await axios.post(endpoint, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
this.imgUrl = `http://localhost:8000${response.data}`;
alert("Success!");
} catch (error) {
console.log(error);
alert(error.response.data);
}
this.imgData = null;
},
},
};
</script>
※原本希望能够实施仅接受图像文件,但本次将省略此功能。
我将修改 frontend/vue.config.js 文件。
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
publicPath: "/",
devServer: {
host: "localhost",
hot: "only",
proxy: {
"^/api": {
target: "http://localhost:8000",
changeOrigin: true,
},
},
},
})
我們將編輯 frontend/src/App.vue 文件,以便顯示 RegisterImage 組件。
<template>
<div>
<!-- <img alt="Vue logo" src="./assets/logo.png" /> -->
<!-- <HelloWorld msg="test" /> -->
<RegisterImage />
</div>
</template>
<script>
// import HelloWorld from "./components/HelloWorld.vue";
import RegisterImage from './components/RegisterImage.vue'
export default {
name: "App",
components: {
// HelloWorld,
RegisterImage
},
};
</script>
...
在这里,我们对后端源代码进行部分编辑。
我将编辑app/views.py文件并对来自前端的注册请求进行修改,以便注册图像数据。
from rest_framework import viewsets, status
from rest_framework.response import Response
from .models import Image
from .serializers import ImageSerializer
class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all()
serializer_class = ImageSerializer
# 以下を追加します
def create(self, request, *args, **kwargs):
# 画像登録処理
img_data = request.data['imageData']
if img_data is not None:
img = Image.objects.create(image=img_data)
return Response(img.image.url,
status=status.HTTP_200_OK)
return Response("Failed to register image.",
status=status.HTTP_400_BAD_REQUEST)
进行画像注册
如果你已经做到这一步了,就试试实际进行注册流程吧。
我会同时启动Django和Vue.js的开发服务器。
(venv)% python manage.py runserver
% cd frontend
% npm run server
在浏览器中打开http://localhost:8080,并确保以下画面打开。



以上就是了。
非常感谢。