This commit is contained in:
Markus Törnqvist 2013-05-19 08:16:09 -07:00
commit 5d73363676
3 changed files with 54 additions and 0 deletions

View 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

View File

@ -12,6 +12,10 @@ factory = RequestFactory()
class BasicView(APIView):
## Uncomment this to see how attribute validation works
# valid_attributes = ('foo', )
# foo = 'foo'
# bar = 'bar'
def get(self, request, *args, **kwargs):
return Response({'method': 'GET'})

View File

@ -10,10 +10,19 @@ from rest_framework.compat import View
from rest_framework.response import Response
from rest_framework.request import Request
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
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
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES