You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django+Rest Framework+LZ4实现POST/GET请求压缩解压问题求助

Hey there! Let's work through your lz4 compression issue with Django 1.11 and DRF step by step, and also cover the GET decompression logic you need.

1. 错误原因分析

The TypeError: a bytes-like object is required, not 'InMemoryUploadedFile' happens because lz4's compression functions (like lz4.frame.compress()) expect raw byte data as input, but you're passing a Django InMemoryUploadedFile object directly. This object is Django's wrapper for uploaded files—not the actual byte content of the file itself.

2. Fixing the POST Compression Logic

First, make sure you've installed the lz4 library:

pip install lz4

Here's how to adjust your POST method to properly handle the uploaded file and compress it:

from rest_framework.views import APIView
from rest_framework.response import Response
import lz4.frame
from .models import FileCompression  # Assume you have a model to store compressed data

class CompressDecompressView(APIView):
    def post(self, request, *args, **kwargs):
        # Grab the uploaded file from the request
        uploaded_file = request.FILES.get('file')
        if not uploaded_file:
            return Response({"error": "No file provided"}, status=400)
        
        try:
            # Read the raw byte content of the uploaded file
            file_bytes = uploaded_file.read()
            
            # Use lz4 frame mode for compression (better for file storage/transfer with built-in checksums)
            compressed_bytes = lz4.frame.compress(file_bytes)
            
            # Save the compressed data to your database (use BinaryField for this)
            FileCompression.objects.create(
                original_filename=uploaded_file.name,
                compressed_data=compressed_bytes,
                original_size=len(file_bytes),
                compressed_size=len(compressed_bytes)
            )
            
            return Response({
                "message": "File compressed successfully",
                "original_size": len(file_bytes),
                "compressed_size": len(compressed_bytes),
                "compression_ratio": round(len(file_bytes)/len(compressed_bytes), 2)
            }, status=201)
        
        except Exception as e:
            return Response({"error": str(e)}, status=500)

Key Notes:

  • uploaded_file.read() converts the uploaded file wrapper into the raw bytes lz4 needs.
  • We use lz4.frame.compress() instead of lz4.block.compress() because frame mode includes metadata and checksums, making it safer for persistent storage and decompression.
3. Implementing GET Decompression Logic

Now add the GET method to retrieve and decompress the stored data:

def get(self, request, file_id, *args, **kwargs):
        try:
            # Fetch the compressed record from the database
            compression_record = FileCompression.objects.get(id=file_id)
            
            # Decompress the stored byte data
            decompressed_bytes = lz4.frame.decompress(compression_record.compressed_data)
            
            # Prepare the response to send the decompressed file back
            response = Response(decompressed_bytes)
            # Set headers to let the client know the file details
            response['Content-Disposition'] = f'attachment; filename="{compression_record.original_filename}"'
            response['Content-Type'] = 'application/octet-stream'  # Adjust to match your file's MIME type if needed
            
            return response
        
        except FileCompression.DoesNotExist:
            return Response({"error": "Compressed file not found"}, status=404)
        except Exception as e:
            return Response({"error": str(e)}, status=500)
4. Required Model Setup

Make sure your FileCompression model uses a BinaryField to store the compressed bytes:

from django.db import models

class FileCompression(models.Model):
    original_filename = models.CharField(max_length=255)
    compressed_data = models.BinaryField()
    original_size = models.IntegerField()
    compressed_size = models.IntegerField()
    created_at = models.DateTimeField(auto_now_add=True)

内容的提问来源于stack exchange,提问作者Philip Mutua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:58:11