1.安装依赖
安装 Pillow 库: 你可以通过以下命令安装 Pillow 库:python -m pip install Pillow
MEDIA_URL 和 MEDIA_ROOT 是 Django 中用于处理用户上传文件的配置项:
MEDIA_URL 是一个 URL 前缀,用于在浏览器中访问上传的文件。例如,MEDIA_URL = '/media/' 表示上传的文件可以通过 /media/ 路径访问。
MEDIA_ROOT 是服务器上存储上传文件的实际目录路径。例如,MEDIA_ROOT = BASE_DIR / 'media' 表示上传的文件将存储在项目的 media 目录下。
2.关于model的配置
class classIndexImageUpload(models.Model):
title = models.CharField(max_length=255, blank=True, null=True)
image_file = models.ImageField(upload_to='uploads/img/Class/')
uploaded_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'codexr_IndexImageUpload'
image_file = models.ImageField(upload_to='uploads/img/Class/') 主要指定文件存储位置
3.设置setting.py设置文件上传根目录MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
将图片文件传到media目录下面存储
4.序列化图片上传的modelclass ClassIndexImageUploadSerializer(serializers.ModelSerializer):
class Meta:
model = classIndexImageUpload
fields = '__all__'
写图片文件上传的view的调用class UploadClassIndexImageView(APIView):
def post(self, request, format=None):
serializer = ClassIndexImageUploadSerializer(data=request.data)
if serializer.is_valid():
# 获取上传的图片路径
image_upload = serializer.save()
# 手动构建URL
image_url = request.build_absolute_uri(
f"{settings.MEDIA_URL}{image_upload.image_file.name.lstrip('/')}")
# 替换路径前缀
image_url = image_url.replace(settings.MEDIA_URL, f"/app1/media/")
serializer_data = serializer.data
serializer_data['image_url'] = image_url
return Response(serializer_data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
url调用 path('upload-Class-IndexImage/', UploadClassIndexImageView.as_view(),
name='upload-Class-IndexImage'),
前台调用示例
const uploadClassIndexImage = async (formData) => {
try {
const res = await apiClient.post('/app1/upload-Class-IndexImage/', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
return res; // 返回响应数据
} catch (error) {
console.error('图片上传失败:', error);
throw error; // 重新抛出错误以便调用方处理
}
}
const handleBeforeUpload = async ({ file }) => {
const formData = new FormData();
formData.append('title', 'Example Title'); // 根据需要添加其他字段
formData.append('image_file', file.file);
// console.log(file);
try {
const response = await uploadClassIndexImage(formData);
console.log(response);
if (response.status === 201) {
newVideo.value.bgImage = response.data.image_url; // 假设后端返回的图片 URL 在 response.data.image_file
message.success('文件上传成功');
}
} catch (error) {
console.error('图片上传失败:', error);
message.error('图片上传失败');
}
// 返回 false 以阻止默认的上传行为
return false;
};
上传图片之后需要设置url应用的路由,如果不设置图片也是无法被前段调用访问if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
5删除图片接口def delete_index_image_file(request):
if request.method == 'POST':
try:
# 解析 JSON 请求体
data = request.body.decode('utf-8')
data_dict = json.loads(data)
image_path_data = data_dict.get('image_path')
if not image_path_data:
return JsonResponse({"error": "没有接受到前端传递删除图片路径"}, status=status.HTTP_400_BAD_REQUEST)
# 去掉 http://localhost:8000/app1/media/ 前缀
image_path = image_path_data.replace(
f"http://{request.get_host()}/app1/media/", "")
# 查找关联的 classIndexImageUpload 实例
try:
image_file = classIndexImageUpload.objects.get(
image_file=image_path)
print(f'图片路径id: {image_file.id}')
except classIndexImageUpload.DoesNotExist:
return JsonResponse({"error": "Image not found in the database"}, status=status.HTTP_404_NOT_FOUND)
# 打印图片路径
print(f'图片路径: {image_file.image_file.path}')
# 删除图片文件
if image_file.image_file:
if os.path.exists(image_file.image_file.path):
os.remove(image_file.image_file.path)
print(f'图片文件已删除: {image_file.image_file.path}')
else:
print(f'图片文件不存在: {image_file.image_file.path}')
# 删除数据库记录
image_file.delete()
print(f'数据库记录已删除: {image_file.id}')
return JsonResponse({"message": "Image deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
except json.JSONDecodeError:
return JsonResponse({"error": "Invalid JSON"}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
return JsonResponse({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
return JsonResponse({"error": "Method not allowed"}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
调用const deleteClassIndexImage = async (data) => {
try {
const resDel = await apiClient.post(`/app1/delete-Class-IndexImage/`, data, {
headers: {
'Content-Type': 'application/json' // 确保设置正确的 Content-Type
}
});
return resDel; // 返回响应数据
} catch (error) {
console.error('请求失败:', error);
throw error; // 重新抛出错误以便调用方处理
}
}
const removeIndexImg = async () => {
try {
console.log({
image_path: newVideo.value.bgImage
});
const deleteRes = await deleteClassIndexImage({
image_path: newVideo.value.bgImage
});
if (deleteRes.status === 204) {
message.success('图片删除成功')
newVideo.value.bgImage = ''
}
} catch (error) {
console.error('图片:', error)
if (error.status === 404) {
message.error('删除外链图片')
newVideo.value.bgImage = ''
}
}
}
|