vbabiy / djangorestframework-camel-case

Camel case JSON support for Django REST framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CamelCaseJSONParser does not care about the field whose name ends with more than two digit

akiyoko opened this issue · comments

Summary

CamelCaseJSONParser does not care about the field whose name ends with more than one digit like this:

  • 'key10' is coverted to 'key_1_0'
  • 'anotherKey10' is coverted to 'another_key_1_0'

I hope the following will occur:

  • 'key10' would be 'key_10'
  • 'anotherKey10' would be 'another_key_10'

Details

My serializer has some fields as follows:

api/serializers.py

from rest_framework import serializers

class FooSerializer(serializers.Serializer):
    key_1 = serializers.IntegerField()
    key_10 = serializers.IntegerField()
    another_key_1 = serializers.IntegerField()
    another_key_10 = serializers.IntegerField()

When I posted the following JSON data to the API using the above serializer,

{
  "key1": 1,
  "key10": 2,
  "anotherKey1": 3,
  "anotherKey10": 4
}

I got the following error response with the status code 400:

{
  "key10":[
    "This field is required."
  ],
  "anotherKey10":[
    "This field is required."
  ]
}

Other prerequisites are as follows:

api/views.py

from rest_framework import status, views
from .serializers import FooSerializer

class FooAPIView(views.APIView):

    def post(self, request, *args, **kwargs):
        serializer = FooSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.data, status.HTTP_200_OK)

mysite/urls.py

from django.urls import path
from api import views as api_view

urlpatterns = [
    path('api/foo/', api_view.FooAPIView.as_view()),
]

mysite/settings.py

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.AllowAny',
    ),
    'DEFAULT_RENDERER_CLASSES': (
        'djangorestframework_camel_case.render.CamelCaseJSONRenderer',
        'rest_framework.renderers.JSONRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'djangorestframework_camel_case.parser.CamelCaseJSONParser',
        'rest_framework.parsers.JSONParser',
    ),
}
>pip list
Package                        Version
------------------------------ -------
Django                         2.2.3
djangorestframework            3.9.4
djangorestframework-camel-case 1.0.3

Cause

CamelCaseJSONParser does not care about the pattern which ends with more than one digit.
The points that should be revised are as follows:

diff --git a/djangorestframework_camel_case/util.py b/djangorestframework_camel_case/util.py
index d8a62d1..5780ecf 100644
--- a/djangorestframework_camel_case/util.py
+++ b/djangorestframework_camel_case/util.py
@@ -42,7 +42,7 @@ def get_underscoreize_re(options):
     if options.get("no_underscore_before_number"):
         pattern = r"([a-z]|[0-9]+[a-z]?|[A-Z]?)([A-Z])"
     else:
-        pattern = r"([a-z]|[0-9]+[a-z]?|[A-Z]?)([A-Z0-9])"
+        pattern = r"([a-z]|[0-9]+[a-z]?|[A-Z]?)([A-Z]|[0-9]+)"
     return re.compile(pattern)


diff --git a/tests.py b/tests.py
index 8fa7b0b..9c9acc6 100644
--- a/tests.py
+++ b/tests.py
@@ -58,6 +58,7 @@ class CamelToUnderscoreTestCase(TestCase):
             "bOnlyOneLetter": 5,
             "onlyCLetter": 6,
             "mix123123aAndLetters": 7,
+            "underscoreBefore123": 8,
         }
         output = {
             "two_word": 1,
@@ -67,6 +68,7 @@ class CamelToUnderscoreTestCase(TestCase):
             "b_only_one_letter": 5,
             "only_c_letter": 6,
             "mix_123123a_and_letters": 7,
+            "underscore_before_123": 8,
         }
         self.assertEqual(underscoreize(data), output)