mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-01 19:10:12 +03:00
Merge 365ad2f600
into 7c945b43f0
This commit is contained in:
commit
5d73363676
41
rest_framework/class_validator.py
Normal file
41
rest_framework/class_validator.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
"""Attribute checking for Python classes
|
||||||
|
"""
|
||||||
|
|
||||||
|
class InvalidAttributeError(AttributeError):
|
||||||
|
"""
|
||||||
|
Use this for invalid attributes because AttributeError means not found
|
||||||
|
"""
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ValidatorMeta(type):
|
||||||
|
"""
|
||||||
|
Metaclass to guard against setting unrecognized attributes
|
||||||
|
Set it as __metaclass__ as low in the inheritance chain as possible
|
||||||
|
"""
|
||||||
|
def __new__(cls, name, parents, kwargs):
|
||||||
|
"""Creates the new class, and sees if it has only known attributes
|
||||||
|
"""
|
||||||
|
new_cls = type.__new__(cls, name, parents, kwargs)
|
||||||
|
|
||||||
|
## Fail only if the new class defines an api
|
||||||
|
if not new_cls.__dict__.has_key('valid_attributes'):
|
||||||
|
return new_cls
|
||||||
|
|
||||||
|
## Do some sanity checks to not fail in vain
|
||||||
|
for attr, val in kwargs.items():
|
||||||
|
if attr == 'valid_attributes':
|
||||||
|
continue
|
||||||
|
if attr.startswith('_'):
|
||||||
|
continue
|
||||||
|
# Methods are always allowed
|
||||||
|
if callable(val):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Ensure validity
|
||||||
|
if not attr in new_cls.valid_attributes:
|
||||||
|
raise InvalidAttributeError(attr)
|
||||||
|
|
||||||
|
return new_cls
|
||||||
|
|
|
@ -12,6 +12,10 @@ factory = RequestFactory()
|
||||||
|
|
||||||
|
|
||||||
class BasicView(APIView):
|
class BasicView(APIView):
|
||||||
|
## Uncomment this to see how attribute validation works
|
||||||
|
# valid_attributes = ('foo', )
|
||||||
|
# foo = 'foo'
|
||||||
|
# bar = 'bar'
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
return Response({'method': 'GET'})
|
return Response({'method': 'GET'})
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,19 @@ from rest_framework.compat import View
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.settings import api_settings
|
from rest_framework.settings import api_settings
|
||||||
|
from rest_framework.class_validator import ValidatorMeta
|
||||||
from rest_framework.utils.formatting import get_view_name, get_view_description
|
from rest_framework.utils.formatting import get_view_name, get_view_description
|
||||||
|
|
||||||
|
|
||||||
class APIView(View):
|
class APIView(View):
|
||||||
|
__metaclass__ = ValidatorMeta
|
||||||
|
valid_attributes = set(('settings', 'renderer_classes', 'parser_classes',
|
||||||
|
'authentication_classes', 'throttle_classes',
|
||||||
|
'permission_classes', 'content_negotiation_class',
|
||||||
|
'allowed_methods', 'default_response_headers',
|
||||||
|
'as_view',
|
||||||
|
))
|
||||||
|
|
||||||
settings = api_settings
|
settings = api_settings
|
||||||
|
|
||||||
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
|
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
|
||||||
|
|
Loading…
Reference in New Issue
Block a user