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 django.contrib.auth.models import AnonymousUser
from djangorestframework import exceptions
from djangorestframework.settings import api_settings
from djangorestframework.utils.mediatypes import is_form_media_type
@ -251,10 +250,26 @@ class Request(object):
return self._not_authenticated()
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.
"""
return getattr(self._request, name)
return getattr(self._request, attr)

View File

@ -15,35 +15,89 @@ API_SETTINGS = {
"""
from django.conf import settings
from djangorestframework import renderers
from django.utils import importlib
from djangorestframework.compat import yaml
DEFAULTS = {
'DEFAULT_RENDERERS': (
renderers.JSONRenderer,
renderers.JSONPRenderer,
# renderers.DocumentingHTMLRenderer,
# renderers.DocumentingXHTMLRenderer,
renderers.DocumentingPlainTextRenderer,
# renderers.XMLRenderer
)
'djangorestframework.renderers.JSONRenderer',
'djangorestframework.renderers.JSONPRenderer',
'djangorestframework.renderers.DocumentingPlainTextRenderer',
),
'DEFAULT_PARSERS': (
'djangorestframework.parsers.JSONParser',
'djangorestframework.parsers.FormParser'
),
'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser',
'UNAUTHENTICATED_TOKEN': None
}
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):
"""
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):
if attr not in DEFAULTS.keys():
raise AttributeError("Invalid API setting: '%s'" % attr)
try:
return settings.API_SETTINGS[attr]
# Check if present in user settings
val = perform_import(settings.API_SETTINGS[attr], attr)
except (AttributeError, KeyError):
# 'API_SETTINGS' does not exist,
# or requested setting is not present in 'API_SETTINGS'.
try:
return DEFAULTS[attr]
except KeyError:
raise AttributeError("No such setting '%s'" % attr)
# Fall back to defaults
val = perform_import(DEFAULTS[attr], attr)
# Cache the result
setattr(self, attr, val)
return val
api_settings = APISettings()