djangoでファイルアップロードのサイズ制限をViewごとに設定する

django/tests/regressiontests/file_uploads/uploadhandler.py at master · django/djangoを参考にサイズ制限ができるUploadHandlerを定義します。

from django.core.files.uploadhandler import FileUploadHandler, StopUpload

class QuotaUploadHandler(FileUploadHandler):
    def __init__(self, request=None, quota_mb=5):
        super(QuotaUploadHandler, self).__init__(request)
        self.total_upload = 0
        self.quota = quota_mb * 2**20

    def receive_data_chunk(self, raw_data, start):
        self.total_upload += len(raw_data)
        if self.total_upload >= self.quota:
            raise StopUpload(connection_reset=True)
        return raw_data

    def file_complete(self, file_size):
        return None

Django | File Uploads | Django documentation
今回はViewごとに制限を行いたいので、View内でUploadHandlerを設定します。

request.upload_handlersにUploadHandlerを追加することで、ViewごとにUploadHandlerを設定することができますが、request.upload_handlersへの操作はrequest.POSTやrequest.FILESにアクセスする前に行う必要があります

通常、CSRF対策としてトークンがPOSTパラメータに含まれており、ビュー関数が実行される前にrequest.POSTにアクセスされてしまいます。これを回避するために一時的にCSRF対策をオフ(@csrf_exempt)にします。

@csrf_exempt
def hoge_view(request):
    @csrf_protect
    def _hoge_view(request):
        # Process ...
        # Return HttpResponse object
        
    # アップロード可能サイズを5 MBに制限する
    request.upload_handlers.insert(0, QuotaUploadHandler(quota_mb=5))
    return _hoge_view(request)