场景描述
前端传递一个表单,表单中有title,description,以及image等信息,image在这里传递的是二进制文件
后端需要将这些数据保存到一个数据库中。image需要保存到指定文件夹下,并且数据库中保存的是image的路径,
之后我们可以通过浏览器访问 类似 127.0.0.1:8000/xxx/a.jpg 访问到这张图片
步骤
这个问题忙活了很久,网上的说法众说纷纭,借助于ChatGpt才将问题得以解决,我的django版本是4.2
- 配置MEDIA的相关信息
我这里的配置如下:
这里的MEDIA_URL就是我们访问时127.0.0.1:8000后面的地址
这里的MEDIA_ROOT则是图片保存的文件夹 - 编写对应的模型,也就是是models.py文件
class ImgSave(models.Model):
title = models.CharField(max_length=50)
description = models.TextField()
imgURL = models.ImageField(upload_to='notices')
- 编写对应的视图函数,用户前端提交表单信息。我们要做的就是将图片保存到刚才配置的MEDIA_ROOT文件夹下,并在数据库中存入对应地址。存入的时候我们使用的是FileSystemStorage,Django自带的媒体文件存储类
# 注意自己引入对应的模型以及方法
from .models import ImgSave
from django.conf import settings
from django.core.files.storage import FileSystemStorage
import os
class SaveImg(View):
def post(self, request):
# media下面的文件夹名字,可以不写,不写就默认是在media文件夹下
# 1. 获取post方法传递过来的数据
file_name = 'notices/'
title = request.POST.get('title')
description = request.POST.get('description')
image = request.FILES.get('image')
# print(title, description, type(image))
# 2. 将图片进行保存,可以用with open的方法进行保存,在django中我们直接自带的FIleSystemStorage
fs = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT,file_name))
img_name = fs.save(image.name, image)
# 3. 对url进行处理,保存成我们浏览器可以直接访问的格式
# /ip:port + /media/ + /notices/ + a.png
img_url = '127.0.0.1:8000'+settings.MEDIA_URL+file_name+img_name
try:
# 4. 将相关信息保存到数据库
ImgSave.objects.create(title=title, description=description, imgURL=img_url)
return JsonResponse({'status':'success','url':img_url},status=200)
except Exception as e:
return JsonResponse({'status': 'error', "msg": e}, status=400)
- 配置表单提交的接口,这里的知识点不再描述。我使用的是面向对象的方式写的视图,所以写法上跟函数式可能有差别,我的二级路由配置如下:
仅作参考 - 在根路由中配置
在urlpatterns的数组后面添加上static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
列出我项目根路由
的信息
相关代码
from django.urls import path, include
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = [
path('admin/', include('BackstageApi.urls')),
path('test/', include('Testing.urls')),
path('', include('ForegroundApi.urls')),
]+static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
结果展示
之后前端通过提交表单的方式将数据进行提交,我们就可以通过返回的url_img数据进行图片的访问
我这里是因为测试的时候该图片已经上传过一次了,也就是存在同名文件,django后台自动做的处理
前端示例代码
仅供参考
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Registration Form</title>
<!-- Import Vue.js from CDN -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Import Bootstrap CSS from CDN -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<!-- Import axios from CDN -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app" class="container">
<h1>Registration Form</h1>
<form>
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input type="text" class="form-control" id="title" v-model="title">
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<input type="text" class="form-control" id="description" v-model="description">
</div>
<div class="mb-3">
<label for="image" class="form-label">Image</label>
<input type="file" class="form-control" id="image" v-on:change="onFileChange">
</div>
<button type="submit" class="btn btn-primary" v-on:click.prevent="submitForm">Submit</button>
</form>
</div>
<script>
new Vue({
el: '#app',
data: {
title: '好吃的不得了',
description: '发射点发射点发射点发法大师傅大师傅撒范德萨',
image: ''
},
methods: {
onFileChange(e) {
this.image = e.target.files[0];
},
submitForm() {
// Handle form submission here
console.log(this.title, this.description, this.image)
let formData = new FormData();
formData.append('title', this.title);
formData.append('description', this.description);
formData.append('image', this.image);
axios.post('http://localhost:8000/test/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
}
});
</script>
</script>
</body>
</html>
标签:返回,description,title,url,MEDIA,image,settings,django
From: https://www.cnblogs.com/zx529/p/17323978.html