├── .github └── workflows │ └── django.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── CHANGES.rst ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.rst ├── pyproject.toml ├── requirements-dev.txt ├── requirements.txt ├── rest_framework_rapidjson ├── __init__.py ├── parsers.py └── renderers.py ├── setup.py └── testproject ├── manage.py ├── pytest.ini ├── rest_framework_rapidjson ├── testapp ├── __init__.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── serializers.py ├── urls.py └── views.py ├── testproject ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py └── tests ├── __init__.py ├── conftest.py └── testapp ├── __init__.py └── test_views.py /.github/workflows/django.yaml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | max-parallel: 4 10 | matrix: 11 | python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] 12 | django: ["3.2.22", "4.1.12", "4.2.4"] 13 | drf: ["3.12.4", "3.13.1", "3.14.0"] 14 | exclude: 15 | - django: "4.2.4" 16 | drf: "3.12.4" 17 | - django: "4.2.4" 18 | drf: "3.13.1" 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Set up Python ${{ matrix.python-version }} 22 | uses: actions/setup-python@v4 23 | with: 24 | python-version: ${{ matrix.python-version }} 25 | - name: Install Dependencies 26 | run: | 27 | python -m pip install --upgrade pip 28 | pip install -q Django==${{ matrix.django }} djangorestframework==${{ matrix.drf }} 29 | pip install -e . 30 | pip install -r requirements-dev.txt 31 | - name: Run lint 32 | run: | 33 | make lint 34 | - name: Run Tests 35 | run: | 36 | make test 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .pytest_cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | *.sqlite3 104 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v4.4.0 4 | hooks: 5 | - id: check-ast 6 | - id: fix-byte-order-marker 7 | - id: check-docstring-first 8 | - id: check-json 9 | - id: check-merge-conflict 10 | - id: check-symlinks 11 | - id: check-toml 12 | - id: check-vcs-permalinks 13 | - id: check-xml 14 | - id: check-yaml 15 | - id: debug-statements 16 | - id: destroyed-symlinks 17 | - id: end-of-file-fixer 18 | - id: trailing-whitespace 19 | 20 | - repo: https://github.com/pycqa/isort 21 | rev: 5.12.0 22 | hooks: 23 | - id: isort 24 | args: ["--overwrite-in-place"] 25 | 26 | - repo: https://github.com/psf/black 27 | rev: 23.9.1 28 | hooks: 29 | - id: black 30 | args: ["--line-length=110"] 31 | 32 | - repo: https://github.com/pycqa/flake8 33 | rev: 6.1.0 34 | hooks: 35 | - id: flake8 36 | args: ["--max-line-length=110", "--ignore=E203,E501,W503"] 37 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | --------- 3 | 4 | 0.2.0 5 | ~~~~~ 6 | 7 | * Drop support for older versions of python and django. 8 | * Replace travisci with github actions. 9 | 10 | 0.1.4 11 | ~~~~~ 12 | 13 | * Adds support to latest python and django versions. 14 | 15 | 0.1.3 16 | ~~~~~ 17 | 18 | * Use number_mode=NM_DECIMAL for loads and dumps. 19 | 20 | 0.1.2 21 | ~~~~~ 22 | 23 | * Improve tests. 24 | 25 | 0.1.1 26 | ~~~~~ 27 | 28 | * Remove python 2.7 from setup.py. 29 | 30 | 0.1.0 31 | ~~~~~ 32 | 33 | * Initial release. 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Allisson Azevedo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include CHANGES.rst 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: clean-pyc 2 | 3 | default: test 4 | 5 | clean-pyc: 6 | @find . -iname '*.py[co]' -delete 7 | @find . -iname '__pycache__' -delete 8 | @find . -iname '.coverage' -delete 9 | @rm -rf htmlcov/ 10 | 11 | clean-dist: 12 | @rm -rf dist/ 13 | @rm -rf build/ 14 | @rm -rf *.egg-info 15 | 16 | clean: clean-pyc clean-dist 17 | 18 | lint: 19 | pre-commit run --all-files 20 | 21 | test: 22 | cd testproject && pytest 23 | 24 | dist: clean 25 | python setup.py sdist 26 | python setup.py bdist_wheel 27 | 28 | release: dist 29 | git tag `python setup.py -q version` 30 | git push origin `python setup.py -q version` 31 | twine upload dist/* 32 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | djangorestframework-rapidjson 2 | ============================= 3 | 4 | Provides `rapidjson `_ 5 | support with parser and renderer. 6 | 7 | .. image:: https://github.com/allisson/django-rest-framework-rapidjson/workflows/tests/badge.svg 8 | :target: https://github.com/allisson/django-rest-framework-rapidjson/actions 9 | 10 | .. image:: https://img.shields.io/pypi/v/djangorestframework-rapidjson.svg 11 | :target: https://pypi.python.org/pypi/djangorestframework-rapidjson 12 | :alt: Latest Version 13 | 14 | .. image:: https://img.shields.io/pypi/pyversions/djangorestframework-rapidjson.svg 15 | :target: https://pypi.python.org/pypi/djangorestframework-rapidjson 16 | :alt: Supported Python versions 17 | 18 | How to install 19 | -------------- 20 | 21 | .. code:: shell 22 | 23 | pip install djangorestframework-rapidjson 24 | 25 | 26 | How to use 27 | ---------- 28 | 29 | Update django rest framework config 30 | 31 | .. code:: python 32 | 33 | REST_FRAMEWORK = { 34 | 'DEFAULT_RENDERER_CLASSES': ( 35 | 'rest_framework_rapidjson.renderers.RapidJSONRenderer', 36 | ), 37 | 'DEFAULT_PARSER_CLASSES': ( 38 | 'rest_framework_rapidjson.parsers.RapidJSONParser', 39 | ) 40 | } 41 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.isort] 2 | profile = "black" 3 | line_length = 110 4 | force_alphabetical_sort_within_sections = true 5 | sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] 6 | default_section = "THIRDPARTY" 7 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | django>=3.2.22 3 | pytest 4 | pytest-cov 5 | pytest-django 6 | twine 7 | wheel 8 | pre-commit 9 | pytz 10 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | python-rapidjson>=1.12 2 | djangorestframework>=3.12.4 3 | -------------------------------------------------------------------------------- /rest_framework_rapidjson/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/rest_framework_rapidjson/__init__.py -------------------------------------------------------------------------------- /rest_framework_rapidjson/parsers.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | 3 | from django.conf import settings 4 | from rapidjson import DM_ISO8601, loads, NM_DECIMAL, UM_CANONICAL 5 | from rest_framework.exceptions import ParseError 6 | from rest_framework.parsers import BaseParser 7 | 8 | from rest_framework_rapidjson.renderers import RapidJSONRenderer 9 | 10 | 11 | class RapidJSONParser(BaseParser): 12 | """ 13 | Parses JSON-serialized data. 14 | """ 15 | 16 | media_type = "application/json" 17 | renderer_class = RapidJSONRenderer 18 | 19 | def parse(self, stream, media_type=None, parser_context=None): 20 | """ 21 | Parses the incoming bytestream as JSON and returns the resulting data. 22 | """ 23 | parser_context = parser_context or {} 24 | encoding = parser_context.get("encoding", settings.DEFAULT_CHARSET) 25 | 26 | try: 27 | decoded_stream = codecs.getreader(encoding)(stream) 28 | return loads( 29 | decoded_stream.read(), 30 | datetime_mode=DM_ISO8601, 31 | uuid_mode=UM_CANONICAL, 32 | number_mode=NM_DECIMAL, 33 | ) 34 | except ValueError as exc: 35 | raise ParseError(f"JSON parse error - {exc}") 36 | -------------------------------------------------------------------------------- /rest_framework_rapidjson/renderers.py: -------------------------------------------------------------------------------- 1 | from rapidjson import DM_ISO8601, dumps, NM_DECIMAL, UM_CANONICAL 2 | from rest_framework.renderers import JSONRenderer 3 | 4 | 5 | class RapidJSONRenderer(JSONRenderer): 6 | def render(self, data, accepted_media_type=None, renderer_context=None): 7 | """ 8 | Render `data` into JSON, returning a bytestring. 9 | """ 10 | if data is None: 11 | return bytes() 12 | 13 | renderer_context = renderer_context or {} 14 | indent = self.get_indent(accepted_media_type, renderer_context) 15 | ret = dumps( 16 | data, 17 | indent=indent, 18 | datetime_mode=DM_ISO8601, 19 | uuid_mode=UM_CANONICAL, 20 | number_mode=NM_DECIMAL, 21 | ) 22 | 23 | # On python 2.x json.dumps() returns bytestrings if ensure_ascii=True, 24 | # but if ensure_ascii=False, the return type is underspecified, 25 | # and may (or may not) be unicode. 26 | # On python 3.x json.dumps() returns unicode strings. 27 | if isinstance(ret, str): 28 | # We always fully escape \u2028 and \u2029 to ensure we output JSON 29 | # that is a strict javascript subset. If bytes were returned 30 | # by json.dumps() then we don't have these characters in any case. 31 | # See: http://timelessrepo.com/json-isnt-a-javascript-subset 32 | ret = ret.replace("\u2028", "\\u2028").replace("\u2029", "\\u2029") 33 | return bytes(ret.encode("utf-8")) 34 | return ret 35 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | import os 3 | import re 4 | 5 | from setuptools import Command, find_packages, setup 6 | 7 | here = os.path.abspath(os.path.dirname(__file__)) 8 | 9 | version = "0.0.0" 10 | changes = os.path.join(here, "CHANGES.rst") 11 | match = r"^#*\s*(?P[0-9]+\.[0-9]+(\.[0-9]+)?)$" 12 | with codecs.open(changes, encoding="utf-8") as changes: 13 | for line in changes: 14 | res = re.match(match, line) 15 | if res: 16 | version = res.group("version") 17 | break 18 | 19 | # Get the long description 20 | with codecs.open(os.path.join(here, "README.rst"), encoding="utf-8") as f: 21 | long_description = f.read() 22 | 23 | # Get version 24 | with codecs.open(os.path.join(here, "CHANGES.rst"), encoding="utf-8") as f: 25 | changelog = f.read() 26 | 27 | 28 | install_requirements = [ 29 | "python-rapidjson>=1.12", 30 | "djangorestframework>=3.12.4", 31 | ] 32 | tests_requirements = [ 33 | "django", 34 | "pytest", 35 | "pytest-cov", 36 | "pytest-django", 37 | ] 38 | 39 | 40 | class VersionCommand(Command): 41 | description = "print library version" 42 | user_options = [] 43 | 44 | def initialize_options(self): 45 | pass 46 | 47 | def finalize_options(self): 48 | pass 49 | 50 | def run(self): 51 | print(version) 52 | 53 | 54 | setup( 55 | name="djangorestframework-rapidjson", 56 | version=version, 57 | description="Provides rapidjson support with parser and renderer", 58 | long_description=long_description, 59 | url="https://github.com/allisson/django-rest-framework-rapidjson", 60 | author="Allisson Azevedo", 61 | author_email="allisson@gmail.com", 62 | classifiers=[ 63 | "Development Status :: 5 - Production/Stable", 64 | "Environment :: Web Environment", 65 | "Intended Audience :: Developers", 66 | "License :: OSI Approved :: MIT License", 67 | "Operating System :: OS Independent", 68 | "Programming Language :: Python", 69 | "Programming Language :: Python :: 3.8", 70 | "Programming Language :: Python :: 3.9", 71 | "Programming Language :: Python :: 3.10", 72 | "Programming Language :: Python :: 3.11", 73 | "Programming Language :: Python :: 3.12", 74 | "Topic :: Internet :: WWW/HTTP", 75 | "Topic :: Software Development :: Libraries :: Application Frameworks", 76 | "Topic :: Software Development :: Libraries :: Python Modules", 77 | ], 78 | keywords="djangorestframework rest json", 79 | packages=find_packages(exclude=["docs", "tests*"]), 80 | setup_requires=["pytest-runner"], 81 | install_requires=install_requirements, 82 | tests_require=tests_requirements, 83 | cmdclass={ 84 | "version": VersionCommand, 85 | }, 86 | ) 87 | -------------------------------------------------------------------------------- /testproject/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testapp.settings") 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == "__main__": 21 | main() 22 | -------------------------------------------------------------------------------- /testproject/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | DJANGO_SETTINGS_MODULE = testproject.settings 3 | addopts = --reuse-db --tb=native -v --cov=rest_framework_rapidjson --cov-report=term-missing 4 | -------------------------------------------------------------------------------- /testproject/rest_framework_rapidjson: -------------------------------------------------------------------------------- 1 | ../rest_framework_rapidjson/ -------------------------------------------------------------------------------- /testproject/testapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/testproject/testapp/__init__.py -------------------------------------------------------------------------------- /testproject/testapp/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class TestappConfig(AppConfig): 5 | name = "testapp" 6 | -------------------------------------------------------------------------------- /testproject/testapp/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | from django.db import migrations, models 2 | 3 | 4 | class Migration(migrations.Migration): 5 | initial = True 6 | dependencies = [] 7 | operations = [ 8 | migrations.CreateModel( 9 | name="MyTestModel", 10 | fields=[ 11 | ( 12 | "id", 13 | models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID"), 14 | ), 15 | ("charfield", models.CharField(max_length=255)), 16 | ("datefield", models.DateField()), 17 | ("datetimefield", models.DateTimeField()), 18 | ("decimalfield", models.DecimalField(decimal_places=2, max_digits=10)), 19 | ("floatfield", models.FloatField()), 20 | ("integerfield", models.IntegerField()), 21 | ("timefield", models.TimeField()), 22 | ("uuidfield", models.UUIDField()), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /testproject/testapp/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/testproject/testapp/migrations/__init__.py -------------------------------------------------------------------------------- /testproject/testapp/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class MyTestModel(models.Model): 5 | charfield = models.CharField(max_length=255) 6 | datefield = models.DateField() 7 | datetimefield = models.DateTimeField() 8 | decimalfield = models.DecimalField(decimal_places=2, max_digits=10) 9 | floatfield = models.FloatField() 10 | integerfield = models.IntegerField() 11 | timefield = models.TimeField() 12 | uuidfield = models.UUIDField() 13 | -------------------------------------------------------------------------------- /testproject/testapp/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework.serializers import ModelSerializer 2 | 3 | from .models import MyTestModel 4 | 5 | 6 | class MyTestModelSerializer(ModelSerializer): 7 | class Meta: 8 | model = MyTestModel 9 | fields = ( 10 | "charfield", 11 | "datefield", 12 | "datetimefield", 13 | "decimalfield", 14 | "floatfield", 15 | "id", 16 | "integerfield", 17 | "timefield", 18 | "uuidfield", 19 | ) 20 | -------------------------------------------------------------------------------- /testproject/testapp/urls.py: -------------------------------------------------------------------------------- 1 | from rest_framework import routers 2 | 3 | from .views import MyTestModelViewSet 4 | 5 | app_name = "testapp" 6 | router = routers.SimpleRouter() 7 | router.register(r"my-test-model", MyTestModelViewSet) 8 | urlpatterns = router.urls 9 | -------------------------------------------------------------------------------- /testproject/testapp/views.py: -------------------------------------------------------------------------------- 1 | from rest_framework.viewsets import ModelViewSet 2 | 3 | from .models import MyTestModel 4 | from .serializers import MyTestModelSerializer 5 | 6 | 7 | class MyTestModelViewSet(ModelViewSet): 8 | queryset = MyTestModel.objects.all() 9 | serializer_class = MyTestModelSerializer 10 | -------------------------------------------------------------------------------- /testproject/testproject/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/testproject/testproject/__init__.py -------------------------------------------------------------------------------- /testproject/testproject/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 4 | 5 | SECRET_KEY = "super-secret-key" 6 | 7 | DEBUG = True 8 | 9 | ALLOWED_HOSTS = ["*"] 10 | 11 | INSTALLED_APPS = [ 12 | "django.contrib.auth", 13 | "django.contrib.contenttypes", 14 | "django.contrib.sessions", 15 | "django.contrib.messages", 16 | "django.contrib.staticfiles", 17 | "rest_framework", 18 | "testapp", 19 | ] 20 | 21 | MIDDLEWARE = [ 22 | "django.middleware.security.SecurityMiddleware", 23 | "django.contrib.sessions.middleware.SessionMiddleware", 24 | "django.middleware.common.CommonMiddleware", 25 | "django.middleware.csrf.CsrfViewMiddleware", 26 | "django.contrib.auth.middleware.AuthenticationMiddleware", 27 | "django.contrib.messages.middleware.MessageMiddleware", 28 | "django.middleware.clickjacking.XFrameOptionsMiddleware", 29 | ] 30 | 31 | ROOT_URLCONF = "testproject.urls" 32 | 33 | TEMPLATES = [ 34 | { 35 | "BACKEND": "django.template.backends.django.DjangoTemplates", 36 | "DIRS": [], 37 | "APP_DIRS": True, 38 | "OPTIONS": { 39 | "context_processors": [ 40 | "django.template.context_processors.debug", 41 | "django.template.context_processors.request", 42 | "django.contrib.auth.context_processors.auth", 43 | "django.contrib.messages.context_processors.messages", 44 | ], 45 | }, 46 | }, 47 | ] 48 | 49 | WSGI_APPLICATION = "testproject.wsgi.application" 50 | 51 | DATABASES = { 52 | "default": { 53 | "ENGINE": "django.db.backends.sqlite3", 54 | "NAME": os.path.join(BASE_DIR, "db.sqlite3"), 55 | } 56 | } 57 | 58 | AUTH_PASSWORD_VALIDATORS = [ 59 | { 60 | "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", 61 | }, 62 | { 63 | "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", 64 | }, 65 | { 66 | "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", 67 | }, 68 | { 69 | "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", 70 | }, 71 | ] 72 | 73 | LANGUAGE_CODE = "en-us" 74 | 75 | TIME_ZONE = "UTC" 76 | 77 | USE_I18N = True 78 | 79 | USE_L10N = True 80 | 81 | USE_TZ = True 82 | 83 | STATIC_URL = "/static/" 84 | 85 | REST_FRAMEWORK = { 86 | "DEFAULT_RENDERER_CLASSES": ("rest_framework_rapidjson.renderers.RapidJSONRenderer",), 87 | "DEFAULT_PARSER_CLASSES": ("rest_framework_rapidjson.parsers.RapidJSONParser",), 88 | } 89 | -------------------------------------------------------------------------------- /testproject/testproject/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import include, path 2 | 3 | urlpatterns = [ 4 | path(r"^test/", include("testapp.urls")), 5 | ] 6 | -------------------------------------------------------------------------------- /testproject/testproject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for testproject project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testproject.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /testproject/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/testproject/tests/__init__.py -------------------------------------------------------------------------------- /testproject/tests/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from rest_framework.test import APIClient 3 | 4 | 5 | @pytest.fixture 6 | def client(): 7 | return APIClient() 8 | -------------------------------------------------------------------------------- /testproject/tests/testapp/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allisson/django-rest-framework-rapidjson/57afe7b60b5fca951482bb58e9f579bd02161be3/testproject/tests/testapp/__init__.py -------------------------------------------------------------------------------- /testproject/tests/testapp/test_views.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from rest_framework import status 3 | from rest_framework.reverse import reverse 4 | from testapp.models import MyTestModel 5 | 6 | pytestmark = pytest.mark.django_db 7 | 8 | 9 | @pytest.fixture 10 | def my_test_model_data(): 11 | return { 12 | "charfield": "charfield", 13 | "datefield": "2017-01-01", 14 | "datetimefield": "2017-01-01T00:00:00Z", 15 | "decimalfield": "100.00", 16 | "floatfield": 100.00, 17 | "integerfield": 100, 18 | "timefield": "00:00:00", 19 | "uuidfield": "6293fec0-6323-4e99-ad42-327b407ffd0f", 20 | } 21 | 22 | 23 | def test_create(client, my_test_model_data): 24 | url = reverse("testapp:mytestmodel-list") 25 | 26 | response = client.post(url, my_test_model_data, format="json") 27 | assert response.status_code == status.HTTP_201_CREATED 28 | for field in my_test_model_data: 29 | assert response.data[field] == my_test_model_data[field] 30 | 31 | 32 | def test_list(client, my_test_model_data): 33 | url = reverse("testapp:mytestmodel-list") 34 | MyTestModel.objects.create(**my_test_model_data) 35 | 36 | response = client.get(url, format="json") 37 | assert response.status_code == status.HTTP_200_OK 38 | assert len(response.data) == 1 39 | for field in my_test_model_data: 40 | assert response.data[0][field] == my_test_model_data[field] 41 | --------------------------------------------------------------------------------