Skip to content

Instantly share code, notes, and snippets.

@ionling
Created March 1, 2020 07:18
Show Gist options
  • Save ionling/6a393c65ac80ca44777f5da6b089988a to your computer and use it in GitHub Desktop.
Save ionling/6a393c65ac80ca44777f5da6b089988a to your computer and use it in GitHub Desktop.
JSON type validate decorator for Django REST framework
import functools
from enum import Enum
from rest_framework.response import Response
class BadRequest(Response):
"""400 Bad Request
May be used to indicate nonspecific failure.
400 is the generic client-side error status, used when no other 4xx error
code is appropriate.
"""
status_code = 400
def bad_request(message: str):
return BadRequest({"message": message})
class JSONDataType(Enum):
"""JSON data types"""
BOOLEAN = "boolean"
NUMBER = "number"
STRING = "string"
OBJECT = "object"
ARRAY = "array"
NULL = "null"
def check_type(self, value):
mapping = {
self.BOOLEAN: bool,
self.NUMBER: (int, float),
self.STRING: str,
self.OBJECT: dict,
self.ARRAY: list,
self.NULL: None,
}
return isinstance(value, mapping[self])
# fmt: off
def request_validate(json_type: JSONDataType):
def validate_decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if not json_type.check_type(args[1].data):
return bad_request(f"Body should be a JSON {json_type.value}")
return func(*args, **kwargs)
return wrapper
return validate_decorator
# fmt: on
# Use it like this
@action(methods=["PUT"], detail=False)
@request_validate(json_type=JSONDataType.OBJECT)
def dog(self, request):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment