Settings suppport importpaths

This commit is contained in:
Tom Christie 2012-09-06 15:42:54 +01:00
parent b7062c5b01
commit 74c50b9535
2 changed files with 90 additions and 21 deletions

View File

@ -11,9 +11,8 @@ The wrapped request then offers a richer API, in particular :
""" """
from StringIO import StringIO from StringIO import StringIO
from django.contrib.auth.models import AnonymousUser
from djangorestframework import exceptions from djangorestframework import exceptions
from djangorestframework.settings import api_settings
from djangorestframework.utils.mediatypes import is_form_media_type from djangorestframework.utils.mediatypes import is_form_media_type
@ -251,10 +250,26 @@ class Request(object):
return self._not_authenticated() return self._not_authenticated()
def _not_authenticated(self): def _not_authenticated(self):
return (AnonymousUser(), None) """
Return a two-tuple of (user, authtoken), representing an
unauthenticated request.
def __getattr__(self, name): By default this will be (AnonymousUser, None).
"""
if api_settings.UNAUTHENTICATED_USER:
user = api_settings.UNAUTHENTICATED_USER()
else:
user = None
if api_settings.UNAUTHENTICATED_TOKEN:
auth = api_settings.UNAUTHENTICATED_TOKEN()
else:
auth = None
return (user, auth)
def __getattr__(self, attr):
""" """
Proxy other attributes to the underlying HttpRequest object. Proxy other attributes to the underlying HttpRequest object.
""" """
return getattr(self._request, name) return getattr(self._request, attr)

View File

@ -15,35 +15,89 @@ API_SETTINGS = {
""" """
from django.conf import settings from django.conf import settings
from djangorestframework import renderers from django.utils import importlib
from djangorestframework.compat import yaml from djangorestframework.compat import yaml
DEFAULTS = { DEFAULTS = {
'DEFAULT_RENDERERS': ( 'DEFAULT_RENDERERS': (
renderers.JSONRenderer, 'djangorestframework.renderers.JSONRenderer',
renderers.JSONPRenderer, 'djangorestframework.renderers.JSONPRenderer',
# renderers.DocumentingHTMLRenderer, 'djangorestframework.renderers.DocumentingPlainTextRenderer',
# renderers.DocumentingXHTMLRenderer, ),
renderers.DocumentingPlainTextRenderer, 'DEFAULT_PARSERS': (
# renderers.XMLRenderer 'djangorestframework.parsers.JSONParser',
) 'djangorestframework.parsers.FormParser'
),
'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
'UNAUTHENTICATED_TOKEN': None
} }
if yaml: if yaml:
DEFAULTS['DEFAULT_RENDERERS'] += (renderers.YAMLRenderer, ) DEFAULTS['DEFAULT_RENDERERS'] += ('djangorestframework.renderers.YAMLRenderer', )
# List of settings that may be in string import notation.
IMPORT_STRINGS = (
'DEFAULT_RENDERERS',
'UNAUTHENTICATED_USER',
'UNAUTHENTICATED_TOKEN'
)
def perform_import(val, setting):
"""
If the given setting is a string import notation,
then perform the necessary import or imports.
"""
if val is None or setting not in IMPORT_STRINGS:
return val
try:
if isinstance(val, basestring):
return import_from_string(val)
elif isinstance(val, (list, tuple)):
return [import_from_string(item) for item in val]
return val
except:
msg = "Could not import '%s' for API setting '%s'" % (val, setting)
raise ImportError(msg)
def import_from_string(val):
"""
Attempt to import a class from a string representation.
"""
# Nod to tastypie's use of importlib.
parts = val.split('.')
module_path, class_name = '.'.join(parts[:-1]), parts[-1]
module = importlib.import_module(module_path)
return getattr(module, class_name)
class APISettings(object): class APISettings(object):
"""
A settings object, that allows API settings to be accessed as properties.
For example:
from djangorestframework.settings import api_settings
print api_settings.DEFAULT_RENDERERS
Any setting with string import paths will be resolved.
"""
def __getattr__(self, attr): def __getattr__(self, attr):
if attr not in DEFAULTS.keys():
raise AttributeError("Invalid API setting: '%s'" % attr)
try: try:
return settings.API_SETTINGS[attr] # Check if present in user settings
val = perform_import(settings.API_SETTINGS[attr], attr)
except (AttributeError, KeyError): except (AttributeError, KeyError):
# 'API_SETTINGS' does not exist, # Fall back to defaults
# or requested setting is not present in 'API_SETTINGS'. val = perform_import(DEFAULTS[attr], attr)
try:
return DEFAULTS[attr] # Cache the result
except KeyError: setattr(self, attr, val)
raise AttributeError("No such setting '%s'" % attr) return val
api_settings = APISettings() api_settings = APISettings()