Skip to content

Commit 776684f

Browse files
committed
Allow conditionally applying files fix middleware
1 parent 0de9885 commit 776684f

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

ninja/compatibility/files.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,21 @@ def fix_request_files_middleware(get_response: Any) -> Any:
2828
populated for POST requests.
2929
https://code.djangoproject.com/ticket/12635
3030
"""
31+
32+
def should_fix_request_files(request: HttpRequest) -> bool:
33+
return (
34+
request.method in FIX_METHODS
35+
and request.content_type != "application/json"
36+
and (
37+
ninja_settings.FIX_REQUEST_FILES_URLS is None
38+
or ninja_settings.FIX_REQUEST_FILES_URLS.search(request.path)
39+
)
40+
)
41+
3142
if iscoroutinefunction(get_response):
3243

3344
async def async_middleware(request: HttpRequest) -> Any:
34-
if (
35-
request.method in FIX_METHODS
36-
and request.content_type != "application/json"
37-
):
45+
if should_fix_request_files(request):
3846
initial_method = request.method
3947
request.method = "POST"
4048
request.META["REQUEST_METHOD"] = "POST"
@@ -48,10 +56,7 @@ async def async_middleware(request: HttpRequest) -> Any:
4856
else:
4957

5058
def sync_middleware(request: HttpRequest) -> Any:
51-
if (
52-
request.method in FIX_METHODS
53-
and request.content_type != "application/json"
54-
):
59+
if should_fix_request_files(request):
5560
initial_method = request.method
5661
request.method = "POST"
5762
request.META["REQUEST_METHOD"] = "POST"

ninja/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
from math import inf
23
from typing import Dict, Optional, Set
34

@@ -29,6 +30,9 @@ class Settings(BaseModel):
2930
FIX_REQUEST_FILES_METHODS: Set[str] = Field(
3031
{"PUT", "PATCH", "DELETE"}, alias="NINJA_FIX_REQUEST_FILES_METHODS"
3132
)
33+
FIX_REQUEST_FILES_URLS: Optional[re.Pattern] = Field(
34+
None, alias="NINJA_FIX_REQUEST_FILES_URLS"
35+
)
3236

3337

3438
settings = Settings.model_validate(django_settings)

tests/test_files.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
import importlib
2+
import re
13
from typing import List
24

35
import pytest
46
from django.core.files.uploadedfile import SimpleUploadedFile
7+
from django.test import override_settings
8+
from django.test.client import MULTIPART_CONTENT
59
from django.utils.datastructures import MultiValueDict
610

711
from ninja import File, NinjaAPI, UploadedFile
12+
from ninja.compatibility.files import fix_request_files_middleware
13+
from ninja.conf import Settings
814
from ninja.errors import ConfigError
915
from ninja.testing import TestClient
1016

@@ -144,3 +150,23 @@ def test_files_fix_middleware():
144150
@api.patch("/file1")
145151
def patch_with_file(request, file: UploadedFile):
146152
return {"name": file.name}
153+
154+
155+
@override_settings(NINJA_FIX_REQUEST_FILES_URLS=re.compile(r"^/file\d+"))
156+
def test_files_fix_middleware_urls(rf):
157+
def get_response(request):
158+
assert request.FILES == {}
159+
160+
from ninja import conf
161+
from ninja.compatibility import files
162+
163+
importlib.reload(conf)
164+
importlib.reload(files)
165+
166+
file = SimpleUploadedFile("test.txt", b"data123")
167+
post_data = rf._encode_data({"file": file}, MULTIPART_CONTENT)
168+
request = rf.generic(
169+
"PATCH", "/not-patched", post_data, content_type=MULTIPART_CONTENT
170+
)
171+
172+
fix_request_files_middleware(get_response)(request)

0 commit comments

Comments
 (0)