Django初窥门径-自定义附件存储模型

前言

Django自带了一个名为FileField的字段,用于处理文件上传。然而,有时我们需要更多的控制权,例如定义文件的存储路径、文件名以及文件类型。在本篇文章中,我们将探讨如何自定义Django附件存储模型。

创建attachment应用

python manage.py startapp attachment

然后,在项目的settings.py文件中,将应用注册到INSTALLED_APPS列表中,如下所示:

INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','rest_framework','drf_yasg2','django_filters','account.apps.AccountConfig','oauth','attachment'
]

创建模型

定义Attachment

from django.db import models# Create your models here.
from rest_framework.reverse import reversefrom CodeVoyager.mixins import BaseModelMixin
import uuidclass BlobField(models.Field):description = 'Blob'def db_type(self, connection):return 'mediumblob'class Attachment(BaseModelMixin):file_id = models.UUIDField(auto_created=True, default=uuid.uuid4, editable=False)file_name = models.CharField('文件名', max_length=200, unique=True)mime_type = models.CharField('MIME类型', max_length=100)file_size = models.PositiveIntegerField('文件长度')blob = BlobField('文件内容')class Meta:verbose_name = '附件'verbose_name_plural = verbose_namedef get_url(self, request):return reverse('attachment:download', request=request, kwargs={'attachment_id': self.file_id})
字段名称类型用途
file_idUUIDField存储文件的唯一标识符
file_nameCharField存储文件的名称,即原始文件名
mime_typeCharField存储文件的MIME类型
file_sizePositiveIntegerField存储文件的大小(以字节为单位)
blob自定义 BlobField存储文件的二进制内容,即文件的实际数据

将更改应用到数据库

python manage.py makemigrations
python manage.py migrate

自定义Django存储

定义存储类

#!/usr/bin/python
# -*- coding: utf-8 -*-from django.core.files.base import ContentFile, File
from django.core.files.storage import Storage
from django.utils.deconstruct import deconstructible@deconstructible
class AttachmentStorage(Storage):"""附件存储"""def __init__(self, model=None):from .models import Attachmentself.model = Attachmentdef _open(self, file_id, mode='rb'):instance = self.model.objects.get(file_id=file_id)file = ContentFile(instance.blob)file.filename = instance.file_namefile.mimetype = instance.mime_typereturn filedef _save(self, name, content: File):blob = content.read()mime_type = getattr(content, 'content_type', 'text/plain')self.model.objects.create(file_name=name,blob=blob,file_size=content.size,mime_type=mime_type)return namedef exists(self, name):return self.model.objects.filter(file_name=name).exists()attachment_storage = AttachmentStorage()
方法名称参数返回值用途
_openfile_id, mode='rb'ContentFile打开文件以供读取,根据给定的file_idAttachment模型中获取文件记录并返回ContentFile对象。
_savename, content: File文件名保存文件,将文件名和文件内容作为参数,创建Attachment模型记录并将文件信息保存到数据库。
existsname布尔值 (TrueFalse)检查文件是否存在,根据给定的文件名查询Attachment模型,返回True如果文件存在,否则返回False

这些方法共同组成了AttachmentStorage类,用于处理附件文件的存储和访问。_open 方法用于读取文件,_save 方法用于保存文件,而exists 方法用于检查文件是否存在。请注意,初始化方法__init__接受一个model参数。

定义视图

上传视图

class AttachmentUploadView(APIView):permission_classes = (permissions.IsAdminUser,)def post(self, request, version):try:file = request.FILES['file']except MultiValueDictKeyError:raise ValidationError('参数错误')name = attachment_storage.save(file.name, file)attachment = get_object_or_404(Attachment, file_name=name)return JsonResponse({'download_url': attachment.get_url(request)}, status=status.HTTP_201_CREATED)
  • 作用:处理附件的上传操作。
  • 功能:当接收到POST请求时,该视图尝试从请求中获取名为 ‘file’ 的文件,然后使用自定义的存储后端 attachment_storage 来保存文件。接着,它在数据库中查找与文件名匹配的附件记录,并返回包含下载链接的 JSON 响应。这个视图的主要目的是允许用户上传附件,并提供上传后的附件的下载链接。

下载视图

class AttachmentDownloadView(APIView):permission_classes = (permissions.IsAuthenticated,)def get(self, request, version, attachment_id=None):attachment = attachment_storage.open(attachment_id)response = HttpResponse(attachment, content_type=attachment.mimetype)response['Content-Disposition'] = 'attachment;filename={name}'.format(name=attachment.filename).encode('utf-8')return response
  • 作用:处理附件的下载操作。
  • 功能:当接收到GET请求时,该视图使用传递的 attachment_id 参数来打开相应的附件。然后,它创建一个包含附件内容的 HTTP 响应对象,设置响应的内容类型为附件的 MIME 类型,并设置响应头 Content-Disposition,指定附件的文件名。最后,它返回包含附件内容的 HTTP 响应。这个视图的主要目的是允许用户通过提供附件的唯一标识符来下载附件。

Content-Disposition 是一个HTTP响应头,它用于指示浏览器如何处理接收到的文件。具体来说,Content-Disposition 头的值告诉浏览器应该如何处理响应的内容,通常用于文件下载操作。

注册视图

#!/usr/bin/python
# -*- coding: utf-8 -*-
from django.urls import re_path, pathfrom .views import AttachmentUploadView, AttachmentDownloadViewapp_name = 'attachment'urlpatterns = [re_path(r'upload', AttachmentUploadView.as_view(), name='upload'),path(r'download/<uuid:attachment_id>', AttachmentDownloadView.as_view(), name='download'),
]

使用swagger测试接口

上传

在这里插入图片描述

下载

在这里插入图片描述

结语

在开发Web应用程序时,文件上传和下载是常见的功能之一,但同时也需要特别关注安全性。通过合理的安全性配置,你可以保护应用程序和用户的数据免受潜在的威胁。在实际的项目中,我们可以增加一些重要的安全性措施,包括文件类型验证、文件大小限制、CSRF保护、存储路径安全性和其他关键措施,以确保文件上传和下载功能的安全性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/133935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python|OpenCV-图像的添加和混合操作(8)

前言 本文是该专栏的第8篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。 在使用OpenCV库对图像操作的时候,有时需要对图像进行运算操作,类似于加法,减法,位操作等处理。而本文,笔者将针对OpenCV对图像的添加,混合以及位操作进行详细的介绍说明和使用。 下面,…

ZKP8.1 Polynomial-IOP and Polynomial Commitment Schemes

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 8: FRI-based Polynomial Commitments and Fiat-Shamir (Justin Thaler) 8.1 Polynomial-IOP and Polynomial Commitment Schemes Recall: build an efficient SNARK Recall: Polynomial-IOP P’s first message in the pro…

YOLOv8轻量化模型:模型轻量化设计 | 轻量级可重参化EfficientRep| 来自YOLOv6思想

💡💡💡本文解决什么问题:在几乎不保证精度下降的前提下,轻量级模型创新设计 EfficientRep 在关键点检测任务中 | GFLOPs从9.6降低至8.5, mAP50从0.921下降至0.912,mAP50-95从0.697提升至0.779 YOLO轻量化模型专栏:http://t.csdnimg.cn/AeaEF 1.YOLOv6介绍 论文…

API接口安全设计

简介 HTTP接口是互联网各系统之间对接的重要方式之一&#xff0c;使用HTTP接口开发和调用都很方便&#xff0c;也是被大量采用的方式&#xff0c;它可以让不同系统之间实现数据的交换和共享。 由于HTTP接口开放在互联网上&#xff0c;所以我们就需要有一定的安全措施来保证接口…

#龙迅视频转换IC LT7911D是一款高性能Type-C/DP/EDP 转MIPI®DSI/CSI/LVDS 芯片,适用于VR/显示应用。

1.说明 应用功能&#xff1a;LT7911D适用于DP1.2转MIPIDSI/MIPICSI/LVDS&#xff0c;EDP转MIPIDSI/MIPICSI/LVDS&#xff0c;TYPE-C转MIPIDSI/MIPICSI/LVDS应用方案 分辨率&#xff1a;单PORT高达4K30HZ&#xff0c;双PORT高达4K 60HZ 工作温度范围&#xff1a;−40C to 85C 产…

webgoat-client side客户端问题

client side Bypass front-end restrictions 用户对 Web 应用程序的前端有很大程度的控制权。 它们可以更改 HTML 代码&#xff0c;有时也可以更改脚本。这就是为什么 需要特定输入格式的应用也应在服务器端进行验证&#xff0c;而不是只在前端做限制。 0x02 先提交请求&am…

win10虚机扩容C盘

需求&#xff1a; 在虚机管理平台上&#xff0c;将win10虚机的C盘空间扩容至200G&#xff0c;当前空间为100G 操作步骤 1.在虚机平台上&#xff0c;将硬盘1的大小增加至200G 如下图 点击保存&#xff1b; 查看win10虚机&#xff0c;发现C盘空间还是100G&#xff0c;如下图…

使用Redis实现缓存及对应问题解决

一、为什么需要Redis作缓存&#xff1f; 在业务场景中&#xff0c;如果有些数据需要极高频的存取&#xff0c;每次都要在mysql中查询的话代价太大&#xff0c;假如有一个存在于客户端和mysql之间的存储空间&#xff0c;每次可以在这空间中进行存取操作&#xff0c;就会减轻mys…

go程序获取工作目录及可执行程序存放目录的方法-linux

简介 工作目录 通常就是指用户启动应用程序时&#xff0c;用户当时所在的文件夹的绝对路径。 如&#xff1a;root用户登录到linux系统后&#xff0c;一顿cd&#xff08;change directory&#xff09;后, 到了/tmp文件夹下。此时&#xff0c;用户要启动某个应用程序&#xff0…

mediapipe流水线分析 二

目标检测 Graph 一 流水线上游输入处理 1 TfLiteConverterCalculator 将输入的数据转换成tensorflow api 支持的Tensor TfLiteTensor 并初始化相关输入输出节点 &#xff0c;该类的业务主要通过 interpreter std::unique_ptrtflite::Interpreter interpreter_ nullptr; 实现…

利用大语言模型(LLM )提高工作效率

日常工作就是面向 google/ 百度编程&#xff0c;除了给变量命名是手动输入&#xff0c;大多时候就是通过搜索引擎拷贝别人的代码&#xff0c;或者找到旧项目一段代码拷贝过来使用。这无疑是开发人员的真实写照&#xff1b;然而&#xff0c;通过搜索引擎搜索答案&#xff0c;无疑…

Go 面向对象,多态

面向对象 工程结构 新建一个oop.go package _oop // Package _oop 引用名称import ("fmt""strconv" )// GIRL 常量 const (// GIRL 自增GIRL Gender iotaFIRSTSECONDTHIRD )type Gender uint8 // 无符号的8位整数类型// User 结构体 type User struct…

代码冲突解决

远程仓库修改 本地代码修改 接下来我们push一下 如果使用IDE 冲突内容如下&#xff1a; 我们可以使用自带的工具进行修改 我们选择接受自己改动的即可 如果使用git工具怎么去处理呢 远程分支是这样 本地是这样的 add和commit之后&#xff0c;再pull&#xff0c;最后pus…

关键词搜索亚马逊商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

亚马逊提供了API接口来获取商品数据。其中&#xff0c;关键词搜索亚马逊商品接口&#xff08;item_search-按关键字搜索亚马逊商品接口&#xff09;可以用于获取按关键字搜索到的商品数据。 通过该接口&#xff0c;您可以使用API Key和API Secret来认证身份&#xff0c;并使用…

BP神经网络的数据分类——语音特征信号分类

大家好&#xff0c;我是带我去滑雪&#xff01; BP神经网络&#xff0c;也称为反向传播神经网络&#xff0c;是一种常用于分类和回归任务的人工神经网络&#xff08;ANN&#xff09;类型。它是一种前馈神经网络&#xff0c;通常包括输入层、一个或多个隐藏层和输出层。BP神经网…

关于iOS:如何使用SwiftUI调整图片大小?

How to resize Image with SwiftUI? 我在Assets.xcassets中拥有很大的形象。 如何使用SwiftUI调整图像大小以缩小图像&#xff1f; 我试图设置框架&#xff0c;但不起作用&#xff1a; 1 2 Image(room.thumbnailImage) .frame(width: 32.0, height: 32.0) 在Image上应用…

浅析刚入门Python初学者的注意事项

文章目录 一、注意你的Python版本1.print()函数2.raw_input()与input()3.比较符号&#xff0c;使用!替换<>4.repr函数5.exec()函数 二、新手常遇到的问题1、如何写多行程序&#xff1f;2、如何执行.py文件&#xff1f;3、and&#xff0c;or&#xff0c;not4、True和False…

Unity项目转微信小游戏保姆教程,繁杂问题解决,及微信小游戏平台简单性能测试

前言 借着某人需求&#xff0c;做了一波简单的技术调研&#xff1a;将Unity项目转换为微信小游戏。 本文主要内容&#xff1a;Unity转换小游戏的步骤&#xff0c;遇到问题的解决方法&#xff0c;以及简单的性能测试对比 微信小游戏的限制 微信小游戏对程序包体大小有严格限制…

Manopt使用

本文记录一些黎曼流型的优化工具箱的使用 入手 安装 https://www.manopt.org/tutorial.html#gettingstarted

飞桨平台搭建PP-YOLOE模型

一、创建项目 此博客仅是运行PP-YOLOE源码&#xff0c;这里以变压器渗漏数据集为例COCO数据集太大了&#xff0c;跑不动&#xff0c;V100训练预估计得7天左右&#xff0c;即便是A100也得4天半&#xff0c;变压器渗漏油数据集跑一个小时左右&#xff0c;还可以接受&#xff0c;…