Django REST framework 自定义图片上传接口

Django+Vue校园二手交易系统全栈实战:从设计到部署 在Web应用开发领域,前后端分离架构已成为主流范式,前端负责交互体验,后端提供数据服务,两者通过API接口通信。Django作为Python生态中最成熟的后端框架,内置ORM、Admin后台和认证体系,能大幅提升业务开发效率;Vue则以组件化和响应式数据绑定见长,适合构建动态交互界面。这套技术栈组合在校园二手交易、电商平台、信息管理系统等场景中应用广泛。文章以校园二手交易系统为例,完整演示了用户认证、商品发布、订单流转、留言互动等核心业务链路的实现过程,并深入讲解了前后端联调中的跨域处理、JWT身份验证、接 阅读详情

前言

使用DRF框架时,默认的图片上传因为自由度低,比较鸡肋,业务需求往往需要一个单独的图片上传接口,在此记录一下实现代码及研究时搞清楚的一些问题。

业务场景

假设写一个门户网站,新闻模块需要上传图片,图片参数名为img。

代码实现

settings.py

图片存储在media文件夹下,配置如下:

from pathlib import Path

MEDIA_URL = '/media/'

PUB_DIR = Path(__file__).resolve().parent.parent

MEDIA_ROOT = os.path.join(PUB_DIR, "media")

models.py

orm设置存储图片字段,设计如下:

from django.db import models

# 新闻
class News(models.Model):
    """ 
    新闻
    """ 
    ...
    img = models.ImageField('展示图片', upload_to="news_img/%Y/%m/", max_length=256, blank=True)
    ...
    
    class Meta:
        verbose_name = '新闻'
        verbose_name_plural = '新闻'

serializers.py

反序列化参数设置如下:

from rest_framework import serializers

class NewsImgUploadSerializer(serializers.Serializer):

    img = serializers.ImageField(
        label="图片",
        max_length=256, # 图片名最大长度
        use_url=True,   # 设为True则URL字符串值将用于输出表示。设为False则文件名字符串值将用于输出表示
        error_messages={
            'invalid': '图片参数错误'
        }
    )

views.py

import logging

from django_filters.rest_framework.backends import DjangoFilterBackend
from django.http import Http404

from rest_framework import mixins, filters, viewsets
from rest_framework import status as rest_status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import exceptions as rest_framework_exceptions

import utils
from . import models, serializers

logger = logging.getLogger(__name__)

# 新闻
class NewsViewSet(viewsets.GenericViewSet):
    """
    新闻
      获取新闻列表,输入参数解释:
      status: 按新闻审核状态筛选
      category: 按新闻分类筛选
      search: 按关键词搜索
        搜索字段包括:('title', 'content')
      ordering: 按字段排序(默认为-update_time)
        可选列表为:('-update_time', )
        默认为正序,如需逆序,在前面加中横杠,例如'-update_time'
    """
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,)
    filter_fields = ('status', 'category')
    search_fields = ('title', 'content')
    ordering_fields = ('id', 'update_time')
    ordering = ('-update_time', )

    def get_queryset(self):
        return models.News.objects.all()

    def get_serializer_class(self):
        if self.action == 'img_upload':
            return serializers.NewsImgUploadSerializer

    @action(detail=False, methods=['post'], url_path="img_upload")
    def img_upload(self, request, pk=None):
        """
        上传新闻图片
        :param request: img 图片路径
        :return:
        """
        try:
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            
            image = serializer.validated_data['img']
            img_file = "news_img" # 图片存储的文件夹

            img_name = utils.save_img(image, img_file)
            img_url = utils.get_img_url(request, img_file, img_name)
            
            return Response(status=rest_status.HTTP_201_CREATED, data=img_url)
        # 未知错误,报服务器内部错误
        except Exception as error:
            logger.error('图片上传失败,错误: %s' % (error))
            return Response(status=rest_status.HTTP_500_INTERNAL_SERVER_ERROR, data={"detail": "服务器内部错误"})

这里有一个小知识点,从serializer中获取到的图片属于InMemoryUploadedFile类型,这种类型数据可以视为一个结构体,要获取到其中的属性可以使用如下的方式:

image_data = [image.file, image.field_name, image.name, image.content_type, image.size, image.charset, image.content_type_extra]

获取到类型的图片后,对图片做了转存操作,方法封装在了utils.py中

utils.py

import random
import os
import datetime
from pathlib import Path

from django.conf import settings

def ranstr(num):
    H = 'abcdefghijklmnopqrstuvwxyz0123456789' 
    H0 = 'abcdefghijklmnopqrstuvwxyz' 

    salt = ''

    salt += random.choice(H0) 
    for i in range(num-1): 
        salt += random.choice(H)

    return salt

# 接收并保存图片
def save_img(image, dest_father_dir):
    # 创建存储路径
    img_dir1 = os.path.join(settings.MEDIA_ROOT, dest_father_dir)
    if not os.path.exists(img_dir1):
        os.mkdir(img_dir1)
    img_dir2 = os.path.join(img_dir1, datetime.datetime.now().strftime("%Y"))
    if not os.path.exists(img_dir2):
        os.mkdir(img_dir2)
    img_file = os.path.join(img_dir2, datetime.datetime.now().strftime("%m"))
    if not os.path.exists(img_file):
        os.mkdir(img_file)

    # 防重名
    p = Path(image.name)
    img_pure_name = p.stem + ranstr(5)
    img_extend_name = p.suffix
    img_name = img_pure_name + img_extend_name

    # 存储图片
    destination = open(os.path.join(img_file, img_name), 'wb+')
    for chunk in image.chunks():
        destination.write(chunk)
    destination.close()

    return  img_name

# 获取图片存储地址
def get_img_url(request, img_file, img_name):
    if request.is_secure():
        protocol = 'https'
    else:
        protocol = 'http'
    # 传回给后端ImageField要存储的图片路径
    backend_relative_path = img_file + '/' + datetime.datetime.now().strftime("%Y") + '/' + datetime.datetime.now().strftime("%m") + '/' + img_name
    relative_path = settings.MEDIA_URL + backend_relative_path
    # 前端显示需要的图片路径
    frontend_url = protocol + '://'+ str(request.META['HTTP_HOST']) + relative_path
    return {"url": frontend_url, "backend_path": backend_relative_path}

urls.py就没什么好写的了,略

相关业务实现逻辑

以上就实现了自定义的图片上传接口,前端上传图片后获得两种图片url,其中url是前端显示用的,可以用于上传后预览图片,backend_path用于传回后端的img字段,将图片存储路径保存起来。

参考资料

关于django中InMemoryUploadedFile图片对象的使用方法 - 旷古的寂寞的博客
django上传文件 - Mr.风的影子的博客
Django中HttpRequest常用参数介绍 - 如何好听的博客
[pathlib]内置pathlib库的常用属性和方法 - [sigai]的博客
学习django之python中os模块的函数 - 心海星的博客

Django实现文件上传下载 本文实例为大家分享了Django实现文件上传下载的具体代码,供大家参考,具体内容如下 一、django实现文件下载 (1)、后台接口 如果从服务器直接将文件路径传给浏览器,普通文件可以直接下载,而图片,html,css和pdf格式等文件会直接显示,所以解决办法就是在头文件中让文件流写入硬盘. ①、最简单的文件下载功能的实现,直接将文件流放入HttpResponse对象即可 def file_download(request): # do something... with open('file_name.txt') as f: c = f.read() return HttpRes 立即下载

相关推荐

PLC编程入门基础知识

PLC即为可编程逻辑控制器,实质是一种专用于工业控制的计算机,其硬件结构基本上与微型计算机相同。

SANRENYIXING的博客 2万+

Django高级扩展之文件上传

文件上传是一个比较常用的网站功能,在服务器端,Django会使用一个叫作request.FILES的对象来处理上传的文件。本文将实现单文件和多文件两种上传。

json_li的博客 4570

AD20.多对多工程中将某个原理图导入PCB工程

AD20将多个原理图中的一个或多个导入到PCB文件中

鬼爷杂货铺 1万+

Django进阶-文件上传

用户可以通过浏览器将图片等文件上传到网站。

m0_43448734的博客 1269

信捷CODESYS平台伺服电机转矩控制模式应用与切换

信捷CODESYS二次开发软件:XS Studio 在运动控制中的转矩控制案例

weixin_64614866的博客 1万+

机器人手眼标定快速精度验证方法

机器人手眼标定快速精度验证方法

laoli_的博客 1万+

Django上传下载文件接口

背景: 使用Django 文件上传下载接口 1.上传文件接口 1.1 上传文件页面 uploads.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&a

LeonTom的博客 5025

手把手教你配置SAP PP供应区域(Supply Area):实现线边仓精准发料与物料流优化

本文详细解析了SAP PP供应区域(Supply Area)的配置方法,帮助企业实现线边仓精准发料与物料流优化。通过三级优先级逻辑和四步配置法,系统可自动识别最优组件来源位置,显著提升生产订单处理效率和库存准确率。文章还提供了典型问题解决方案和性能优化技巧,适用于离散制造和重复制造场景。

weixin_29275257的博客 434

基于Django+Vue实现文件上传下载

基于Django+Vue实现文件上传下载

weixin_44192903的博客 2538

SAP_PP模块中MRP中信号灯简介

一、信号灯的作用二、常见的信号灯颜色及含义三、信号灯的来源四、常见场景示例示例1:物料满足所有需求示例2:生产订单已延迟示例3:缺料或未产生计划订单五、相关事务码参考六、如何应对红色或黄色信号灯?七、前台操作说明在 SAP PP 模块中,**MRP(物料需求计划)运行结果中的“信号灯”是一种非常直观的可视化提示工具,用于帮助用户快速识别物料计划是否存在异常或需要关注的问题。这些信号灯通常出现在MD04(库存/需求清单)、MD05(单物料MRP清单)、MD07(MRP列表)**等事务代码的界面中。

我小时候很黑的博客 633

教你如何阅读Autosar代码(6):常量变量定义

编译器抽象应该为常量的声明和定义定义CONST宏。编译器抽象应该定义VAR宏来声明和定义变量。memclass:常量本身的分类;memclass:变量本身的分类;vartype:变量的类型;type:常量的类型;

wdconan001的博客 958

Django REST Framework 从入门到精通

本文是Django REST Framework(DRF)的完整学习指南,从基础到进阶全面讲解DRF的核心功能。主要内容包括: 基础概念:介绍DRF的作用、核心能力(序列化、视图、路由等)和优势。 环境配置:详细说明安装步骤和项目配置方法,包含JWT认证、过滤等扩展功能的集成。 快速入门:通过图书管理API示例,演示如何: 定义数据模型 创建序列化器 实现增删改查视图(使用generics类) 配置URL路由 完整学习路线:提供20个核心主题的学习目录,涵盖认证权限、分页过滤、限流、文件上传、API文档等高

qq_30903893的博客 337

大模型安全-生成检测-事实核查-攻击-防御-思考-记忆-融合-语音相关研究 2025年版

本文整理了关于大模型安全领域的综合性资源,包括7篇综述论文、9个安全数据集以及5篇强化学习相关的安全研究论文。主要涉及大模型的对抗攻击、隐私保护、安全评估等方向,涵盖TruthfulQA、ToxiGen等知名数据集和TrustLLM、HarmBench等关键研究。资源包括知乎博主分享、arXiv预印本和顶会论文,并附有详细的中文讲解链接,为研究者提供了系统性的安全研究参考。

CSPhD-winston的博客 3589

drf-extra-fields终极指南:解锁Django Rest Framework的高级字段功能

drf-extra-fields是Django Rest Framework(DRF)的增强插件,提供了多种实用的高级字段类型,帮助开发者轻松实现复杂数据处理需求。本文将全面介绍这些强大字段的使用方法,让你的API开发效率提升300%!🚀 ## 为什么选择drf-extra-fields? 在DRF开发中,你是否遇到过这些痛点: - 需要处理Base64格式的图片上传 - 要实现地理位置数据

gitblog_00027的博客 957

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

drf-extra-fields源码解析:如何优雅扩展Django Rest Framework功能

drf-extra-fields是Django Rest Framework(DRF)的强大扩展库,提供了多种实用字段类型,帮助开发者轻松实现文件上传、地理数据处理、范围查询等常见功能。本文将深入解析其核心实现机制,展示如何通过简单集成提升API开发效率。 ## 🌟核心功能概览:10+实用字段类型 drf-extra-fields在`drf_extra_fields/fields.py`和`

gitblog_00053的博客 691

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

rest接口_使用Django开发rest接口

Rest Api接口开发核心任务将请求的数据(如json格式)转换为模型类对象-反序列化操作数据库将模型类对象转换为响应的数据(如json格式)-序列化Django Rest frameworkDRF框架是建立在Django基础上,用于构建Rest web Api的强大而灵活的工具,通常在序列化和反序列化时,虽然操作的数据不相同,但是执行的过程是相似的,也就是部分代码是可以复用简化编写,并且增删改...

weixin_39638057的博客 401

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

3小时快速搭建Django REST Framework API服务:从零到生产级骨架

在前后端分离架构中,RESTful API作为数据交互的核心桥梁,其设计规范与开发效率直接影响项目进度。Django REST Framework(DRF)基于Django生态,通过序列化器、视图集和路由器等组件,将模型数据高效转换为JSON格式,并遵循REST约束提供标准化的端点。其技术价值在于大幅降低API开发复杂度,内置的认证、权限、限流和文档生成机制,让开发者能聚焦业务逻辑而非基础设施。在Web应用、移动端后端及微服务等场景,DRF结合JWT认证和CORS处理,能快速构建安全、可扩展的API服务。本

weixin_34161032的博客 367

django-rest-framework批量上传文件

models.py #models from django.utils.timezone import now class MoreImage(models.Model): """ 多传图片 """ del_choices = (('0', '未删除'),('1', '已删除')) now = str(now().strftime('%Y_%m')) objectType = models.CharField(max_length=30, verbose_.

Samle的博客 1687

Vue3+TypeScript+Django Rest Framework 搭建个人博客

本文适合对有 Python 语言有一定基础的人群,希望利用 Python 做更多有意思的事情,比如搭建个人博客,记录自己的所思所想,或者想找一个项目实践前后端分离技术等等。跟着本文可以了解和运行项目,本项目是在 Window 10 Professional 系统下开发。 大家好!我是 落霞孤鹜 ,从今天开始一步一步搭建一套基于 Python 语言的个人博客, 这个项目也是我的个人博客搭建过程的记录,在实现过程中踏过了很多坑,这些坑也会在实现具体功能时列举出来,希望能帮助到可能遇到同样问题的你。 整个项目.

zgj0607的博客 760

【Django DRF Apps】从零搭建一个上传图片app

以下是一个通过 Django REST Framework (DRF) 实现图片上传功能的完整示例,涵盖从环境配置到功能实现的所有步骤,同时增加了功能点和知识点的解析,便于理解与扩展。通过以上步骤,你将实现一个功能完整且安全的图片上传 API,同时具备高可扩展性,支持未来在生产环境中的部署与优化。

qq_59344127的博客 1356

前端:iview Upload组件上传图片,后端:django rest framework 的serializers.ModelSerializer完成图片保存并入库

折腾了很长时间,经过查阅很多文档,最后找到了解决办法,现分享出来,希望可以给大家一点帮助,如果有更好的解决方法,请@我,谢谢。 转载,请标明,尊重原创,从你我他开始。 需求:通过iview-admin2.5的Upload上传组件,上传到后端的DRF的API接口。 问题:通过DRF自带的接口测试和xadmin后台测试,上传均正常。但通过iview过来的图片就无法上传。 解决办法:在ser...

xiguatony的博客 834

iView组件+Django实现前后端分离上传图片

文章目录iView组件+Django实现前后端分离上传图片#1 环境#2 前端#3 后端#3.1 原生的Django#3.1 Django Rest Framework iView组件+Django实现前后端分离上传图片 #1 环境 Vue "vue": "^2.5.2", "axios": "^0.19.0", "vue-axios": "^2.1.4", "vue-router": "^3.0...

Auto 2269

drf-extra-fields核心组件解析:从Base64ImageField到RangeField

drf-extra-fields是Django Rest Framework的扩展工具库,提供了多种实用的字段类型,帮助开发者轻松处理复杂数据格式。本文将深入解析两个核心组件:Base64ImageField和RangeField,展示它们如何简化文件上传和范围数据处理。 ## Base64ImageField:简化图片上传的终极方案 Base64ImageField是处理图片上传的强力工具,

gitblog_00843的博客 1104

YOLO+Django+Vue构建工业缺陷检测系统实战

计算机视觉中的目标检测技术(如YOLO系列算法)通过深度学习实现高精度物体识别,其核心原理是利用卷积神经网络提取图像特征并进行边界框预测。在工业领域,将检测模型部署为Web服务能显著提升生产效率,本文介绍的Django+Vue前后端分离架构正是典型实现方案。通过RESTful API解耦前后端,配合PyTorch的模型推理优化,系统在制造业缺陷检测场景中实现1.8秒端到端响应。该方案采用Vue3组合式API提升开发效率,利用Django ORM实现检测记录管理,其模型热插拔设计和客户端压缩策略对工业物联网(

cuyi7076的博客 374

java rest 图片上传_django rest 实现多图片上传

models 配置 class ImageItems(models.Model):image = models.ImageField(upload_to='static/images/%Y/%m/%d', null=False, blank=False, verbose_name='图片url')class Meta:verbose_name = '图片集合'verbose_name_plural...

weixin_39742727的博客 183

使用Trae开发微信小程序(智能换背景)学习:从Coze工作流到Django接口的完整落地

用Trae生成微信小程序与Django骨架,把Coze换背景工作流封装成Python接口,再通过TaoToken统一模型调用入口,完成上传、轮询、展示全链路。文中给出可复制的Django路由、Coze参数与小程序请求示例,并排查401、local proxy failed等常见报错。官网:https://taotoken.net/?utm_source=taotoken_aicg_blog_end

weixin_42575505的博客 130
上一篇: Django restframework 实现文件下载 实现详解及踩坑记录
下一篇: Django Admin 管理后台添加自定义信息及定制化页面
ZeroChia
博客等级 码龄9年 8粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值