在Django REST Framework中用LZ4处理含图片请求的压缩与解压
在Django类视图中使用LZ4压缩/解压上传的文档
嘿,我来帮你搞定这个需求!要在POST上传文档后自动用LZ4压缩,还能提供解压下载的链接,咱们可以按下面的步骤一步步来:
1. 先安装LZ4依赖
首先得把LZ4的Python包装上,打开终端跑这个命令:
pip install lz4
2. 调整你的模型
咱们需要给EmployeeDocument模型加一个字段来存储压缩后的文件,这样后续才能提供解压服务。修改后的模型大概是这样:
# models.py from django.db import models from lz4.frame import compress, decompress import os from django.core.files.base import ContentFile class EmployeeDocument(models.Model): """ Model, Which holds Employee documents uploaded. """ employee = models.ForeignKey( Employee, related_name="employee_docs", null=True, blank=True, on_delete=models.SET_NULL) document = models.FileField(upload_to='employee_docs/original/') # 新增字段存储压缩后的文件 compressed_document = models.FileField(upload_to='employee_docs/compressed/', blank=True, null=True) def compress_document(self): """用LZ4压缩上传的原始文件""" if self.document and not self.compressed_document: # 读取原始文件内容 self.document.open() file_content = self.document.read() self.document.close() # 用LZ4压缩(frame格式带校验,更适合文件存储) compressed_content = compress(file_content) # 生成压缩后的文件名,比如在原文件名后加.lz4后缀 original_name = os.path.splitext(self.document.name)[0] compressed_filename = f"{original_name}.lz4" # 将压缩内容保存到compressed_document字段 self.compressed_document.save(compressed_filename, ContentFile(compressed_content), save=False) def save(self, *args, **kwargs): # 保存前自动触发压缩逻辑 self.compress_document() super().save(*args, **kwargs)
3. 实现解压的类视图
接下来写一个专门处理解压请求的视图,让用户能下载解压后的原始文件:
# views.py from django.views.generic import View from django.http import HttpResponse from lz4.frame import decompress from .models import EmployeeDocument import os class DecompressDocumentView(View): def get(self, request, doc_id): try: emp_doc = EmployeeDocument.objects.get(id=doc_id) if not emp_doc.compressed_document: return HttpResponse("未找到对应的压缩文件", status=404) # 读取压缩文件内容 emp_doc.compressed_document.open() compressed_content = emp_doc.compressed_document.read() emp_doc.compressed_document.close() # 执行解压操作 decompressed_content = decompress(compressed_content) # 还原原始文件名(去掉.lz4后缀) original_filename = os.path.splitext(emp_doc.compressed_document.name)[0].split('/')[-1] # 返回解压后的文件供下载 response = HttpResponse(decompressed_content, content_type='application/octet-stream') response['Content-Disposition'] = f'attachment; filename="{original_filename}"' return response except EmployeeDocument.DoesNotExist: return HttpResponse("指定文档不存在", status=404) except Exception as e: return HttpResponse(f"解压失败: {str(e)}", status=500)
4. 整合到POST上传的类视图
如果你用CreateView处理文档上传,可以在上传成功后把解压链接传递给前端模板:
# views.py from django.views.generic.edit import CreateView from .models import EmployeeDocument from .forms import EmployeeDocumentForm class EmployeeDocumentCreateView(CreateView): model = EmployeeDocument form_class = EmployeeDocumentForm success_url = '/employee-docs/' # 替换成你的实际成功跳转URL def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 上传成功后,把解压链接加入上下文 if self.object: context['decompress_url'] = f'/decompress/{self.object.id}/' return context
5. 配置URL路由
最后在你的urls.py里添加对应的路由规则:
# urls.py from django.urls import path from .views import EmployeeDocumentCreateView, DecompressDocumentView urlpatterns = [ path('upload-doc/', EmployeeDocumentCreateView.as_view(), name='upload_doc'), path('decompress/<int:doc_id>/', DecompressDocumentView.as_view(), name='decompress_doc'), ]
这样一来,用户上传文档后,系统会自动用LZ4压缩并保存,你可以在上传成功页面通过{{ decompress_url }}展示解压链接,用户点击就能下载解压后的原始文件啦!
内容的提问来源于stack exchange,提问作者Philip Mutua
相关产品推荐
相关产品推荐

