Skip to content

Commit

Permalink
add middleware support for djangorestframework_camel_case
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Jun 19, 2023
1 parent a11b545 commit e98b40d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 12 deletions.
25 changes: 21 additions & 4 deletions drf_spectacular/contrib/djangorestframework_camel_case.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import re
from typing import Optional

from django.utils.module_loading import import_string


def camelize_serializer_fields(result, generator, request, public):
from django.conf import settings
from djangorestframework_camel_case.settings import api_settings
from djangorestframework_camel_case.util import camelize_re, underscore_to_camel

Expand All @@ -11,6 +14,19 @@ def camelize_serializer_fields(result, generator, request, public):
# ignore certain field names while camelizing
ignore_keys = api_settings.JSON_UNDERSCOREIZE.get("ignore_keys") or ()

def has_middleware_installed():
try:
from djangorestframework_camel_case.middleware import CamelCaseMiddleWare
except ImportError:
return False

for middleware in [import_string(m) for m in settings.MIDDLEWARE]:
try:
if issubclass(CamelCaseMiddleWare, middleware):
return True
except TypeError:
pass

def camelize_str(key: str) -> str:
new_key = re.sub(camelize_re, underscore_to_camel, key) if "_" in key else key
if key in ignore_keys or new_key in ignore_keys:
Expand All @@ -36,10 +52,11 @@ def camelize_component(schema: dict, name: Optional[str] = None) -> dict:
if component_type == 'schemas':
camelize_component(component.schema)

for url_schema in result["paths"].values():
for method_schema in url_schema.values():
for parameter in method_schema.get("parameters", []):
parameter["name"] = camelize_str(parameter["name"])
if has_middleware_installed():
for url_schema in result["paths"].values():
for method_schema in url_schema.values():
for parameter in method_schema.get("parameters", []):
parameter["name"] = camelize_str(parameter["name"])

# inplace modification of components also affect result dict, so regeneration is not necessary
return result
34 changes: 30 additions & 4 deletions tests/contrib/test_djangorestframework_camel_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing_extensions import TypedDict

from drf_spectacular.contrib.djangorestframework_camel_case import camelize_serializer_fields
from drf_spectacular.utils import extend_schema, OpenApiParameter
from drf_spectacular.utils import OpenApiParameter, extend_schema
from tests import assert_schema, generate_schema


Expand Down Expand Up @@ -49,8 +49,8 @@ def get_field_nested_ignored(self) -> NestedObject: # type: ignore
@extend_schema(
parameters=[
OpenApiParameter(
name="field_one",
description="filter_field",
name="field_parameter",
description="filter_parameter",
required=False,
type=str,
),
Expand Down Expand Up @@ -78,8 +78,34 @@ def home(self, request):
}
)
@pytest.mark.contrib('djangorestframework_camel_case')
def test_camelize_serializer_fields():
def test_camelize_serializer_fields(no_warnings):
assert_schema(
generate_schema('a_b_c', FakeViewset),
'tests/contrib/test_djangorestframework_camel_case.yml'
)


@mock.patch(
'django.conf.settings.MIDDLEWARE',
['djangorestframework_camel_case.middleware.CamelCaseMiddleWare'],
create=True
)
@mock.patch(
'drf_spectacular.settings.spectacular_settings.POSTPROCESSING_HOOKS',
[camelize_serializer_fields]
)
@mock.patch(
'djangorestframework_camel_case.settings.api_settings.JSON_UNDERSCOREIZE',
{
'no_underscore_before_number': False,
'ignore_fields': ('field_nested_ignored',),
'ignore_keys': ('field_ignored',),
}
)
@pytest.mark.contrib('djangorestframework_camel_case')
def test_camelize_middleware(no_warnings):
assert_schema(
generate_schema('a_b_c', FakeViewset),
'tests/contrib/test_djangorestframework_camel_case.yml',
reverse_transforms=[lambda x: x.replace("field_parameter", "fieldParameter")]
)
8 changes: 4 additions & 4 deletions tests/contrib/test_djangorestframework_camel_case.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ paths:
operationId: a_b_c_list
parameters:
- in: query
name: fieldOne
name: field_parameter
schema:
type: string
description: filter_field
description: filter_parameter
tags:
- a_b_c
security:
Expand All @@ -32,10 +32,10 @@ paths:
operationId: a_b_c_home_retrieve
parameters:
- in: query
name: fieldOne
name: field_parameter
schema:
type: string
description: filter_field
description: filter_parameter
tags:
- a_b_c
security:
Expand Down

0 comments on commit e98b40d

Please sign in to comment.