django图片文件上传攻略

[复制链接]
查看: 58   回复: 0

340

主题

340

帖子

1933

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1933
1.png

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.序列化图片上传的model
class 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 = ''
        }
        
    }

}


回复

使用道具 举报

您需要登录后才可以回帖   登录 立即注册

高级模式

南通谢凡软件科技有限公司