From 4b691c402707775c3048a90531024f3bc5be6f91 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:06:27 +0100 Subject: Change package name: djangorestframework -> rest_framework --- rest_framework/settings.py | 125 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 rest_framework/settings.py (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py new file mode 100644 index 00000000..fef8097e --- /dev/null +++ b/rest_framework/settings.py @@ -0,0 +1,125 @@ +""" +Settings for REST framework are all namespaced in the REST_FRAMEWORK setting. +For example your project's `settings.py` file might look like this: + +REST_FRAMEWORK = { + 'DEFAULT_RENDERERS': ( + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.YAMLRenderer', + ) + 'DEFAULT_PARSERS': ( + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.YAMLParser', + ) +} + +This module provides the `api_setting` object, that is used to access +REST framework settings, checking for user settings first, then falling +back to the defaults. +""" +from django.conf import settings +from django.utils import importlib + + +DEFAULTS = { + 'DEFAULT_RENDERERS': ( + 'rest_framework.renderers.JSONRenderer', + 'rest_framework.renderers.JSONPRenderer', + 'rest_framework.renderers.DocumentingHTMLRenderer', + 'rest_framework.renderers.DocumentingPlainTextRenderer', + ), + 'DEFAULT_PARSERS': ( + 'rest_framework.parsers.JSONParser', + 'rest_framework.parsers.FormParser' + ), + 'DEFAULT_AUTHENTICATION': ( + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.UserBasicAuthentication' + ), + 'DEFAULT_PERMISSIONS': (), + 'DEFAULT_THROTTLES': (), + 'DEFAULT_CONTENT_NEGOTIATION': 'rest_framework.negotiation.DefaultContentNegotiation', + + 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', + 'UNAUTHENTICATED_TOKEN': None, + + 'FORM_METHOD_OVERRIDE': '_method', + 'FORM_CONTENT_OVERRIDE': '_content', + 'FORM_CONTENTTYPE_OVERRIDE': '_content_type', + 'URL_ACCEPT_OVERRIDE': '_accept', + 'URL_FORMAT_OVERRIDE': 'format', + + 'FORMAT_SUFFIX_KWARG': 'format' +} + + +# List of settings that may be in string import notation. +IMPORT_STRINGS = ( + 'DEFAULT_RENDERERS', + 'DEFAULT_PARSERS', + 'DEFAULT_AUTHENTICATION', + 'DEFAULT_PERMISSIONS', + 'DEFAULT_THROTTLES', + 'DEFAULT_CONTENT_NEGOTIATION', + '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 not setting in IMPORT_STRINGS: + return val + + if isinstance(val, basestring): + return import_from_string(val, setting) + elif isinstance(val, (list, tuple)): + return [import_from_string(item, setting) for item in val] + return val + + +def import_from_string(val, setting): + """ + Attempt to import a class from a string representation. + """ + try: + # 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) + except: + msg = "Could not import '%s' for API setting '%s'" % (val, setting) + raise ImportError(msg) + + +class APISettings(object): + """ + A settings object, that allows API settings to be accessed as properties. + For example: + + from rest_framework.settings import api_settings + print api_settings.DEFAULT_RENDERERS + + Any setting with string import paths will be automatically resolved + and return the class, rather than the string literal. + """ + def __getattr__(self, attr): + if attr not in DEFAULTS.keys(): + raise AttributeError("Invalid API setting: '%s'" % attr) + + try: + # Check if present in user settings + val = perform_import(settings.REST_FRAMEWORK[attr], attr) + except (AttributeError, KeyError): + # Fall back to defaults + val = perform_import(DEFAULTS[attr], attr) + + # Cache the result + setattr(self, attr, val) + return val + +api_settings = APISettings() -- cgit v1.2.3 From d9cba6398e2323b8d8cd34f791442528517e01b4 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 17:44:34 +0100 Subject: Clean up bits of templates etc --- rest_framework/settings.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index fef8097e..a0b99010 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -24,9 +24,7 @@ from django.utils import importlib DEFAULTS = { 'DEFAULT_RENDERERS': ( 'rest_framework.renderers.JSONRenderer', - 'rest_framework.renderers.JSONPRenderer', 'rest_framework.renderers.DocumentingHTMLRenderer', - 'rest_framework.renderers.DocumentingPlainTextRenderer', ), 'DEFAULT_PARSERS': ( 'rest_framework.parsers.JSONParser', @@ -38,7 +36,8 @@ DEFAULTS = { ), 'DEFAULT_PERMISSIONS': (), 'DEFAULT_THROTTLES': (), - 'DEFAULT_CONTENT_NEGOTIATION': 'rest_framework.negotiation.DefaultContentNegotiation', + 'DEFAULT_CONTENT_NEGOTIATION': + 'rest_framework.negotiation.DefaultContentNegotiation', 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, -- cgit v1.2.3 From 09a445b257532be69ffab69a3f62b84bfa90463d Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 26 Sep 2012 12:40:11 +0100 Subject: Bits of cleanup --- rest_framework/settings.py | 1 + 1 file changed, 1 insertion(+) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index a0b99010..312d707d 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -29,6 +29,7 @@ DEFAULTS = { 'DEFAULT_PARSERS': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser' + 'rest_framework.parsers.MultiPartParser' ), 'DEFAULT_AUTHENTICATION': ( 'rest_framework.authentication.SessionAuthentication', -- cgit v1.2.3 From ffe2c6d558a4d7843a1efed0af5bd0908892ef70 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 26 Sep 2012 13:09:20 +0100 Subject: Add missing comma --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 312d707d..a498b222 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -28,7 +28,7 @@ DEFAULTS = { ), 'DEFAULT_PARSERS': ( 'rest_framework.parsers.JSONParser', - 'rest_framework.parsers.FormParser' + 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ), 'DEFAULT_AUTHENTICATION': ( -- cgit v1.2.3 From 0cc7030aab9f2b97ce6b5db55d6d1a8a32d50231 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 26 Sep 2012 21:47:19 +0100 Subject: Fix @api_view decorator tests --- rest_framework/settings.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index a498b222..cfc89fe1 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -39,6 +39,10 @@ DEFAULTS = { 'DEFAULT_THROTTLES': (), 'DEFAULT_CONTENT_NEGOTIATION': 'rest_framework.negotiation.DefaultContentNegotiation', + 'DEFAULT_THROTTLE_RATES': { + 'user': None, + 'anon': None, + }, 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, -- cgit v1.2.3 From 6fa589fefd48d98e4f0a11548b6c3e5ced58e31e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sun, 30 Sep 2012 17:31:28 +0100 Subject: Pagination support --- rest_framework/settings.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index cfc89fe1..8387fd29 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -44,6 +44,10 @@ DEFAULTS = { 'anon': None, }, + 'MODEL_SERIALIZER': 'rest_framework.serializers.ModelSerializer', + 'PAGINATION_SERIALIZER': 'rest_framework.pagination.PaginationSerializer', + 'PAGINATE_BY': 20, + 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, @@ -65,6 +69,8 @@ IMPORT_STRINGS = ( 'DEFAULT_PERMISSIONS', 'DEFAULT_THROTTLES', 'DEFAULT_CONTENT_NEGOTIATION', + 'MODEL_SERIALIZER', + 'PAGINATION_SERIALIZER', 'UNAUTHENTICATED_USER', 'UNAUTHENTICATED_TOKEN', ) -- cgit v1.2.3 From e7685f3eb5c7d7e8fb1678d673f03688012b00cb Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 2 Oct 2012 15:24:42 +0100 Subject: URL overrides in settings fixed up slightly --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 8387fd29..2e50e05d 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -54,7 +54,7 @@ DEFAULTS = { 'FORM_METHOD_OVERRIDE': '_method', 'FORM_CONTENT_OVERRIDE': '_content', 'FORM_CONTENTTYPE_OVERRIDE': '_content_type', - 'URL_ACCEPT_OVERRIDE': '_accept', + 'URL_ACCEPT_OVERRIDE': 'accept', 'URL_FORMAT_OVERRIDE': 'format', 'FORMAT_SUFFIX_KWARG': 'format' -- cgit v1.2.3 From d89d6887d2eb8293348cb1a7a043a05352819cb8 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 4 Oct 2012 11:26:41 +0100 Subject: HyperlinkedModelSerializer with working HyperlinkedIdentityField, but no hyperlinked relations --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 2e50e05d..ccc8f368 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -46,7 +46,7 @@ DEFAULTS = { 'MODEL_SERIALIZER': 'rest_framework.serializers.ModelSerializer', 'PAGINATION_SERIALIZER': 'rest_framework.pagination.PaginationSerializer', - 'PAGINATE_BY': 20, + 'PAGINATE_BY': None, 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', 'UNAUTHENTICATED_TOKEN': None, -- cgit v1.2.3 From 97a7f27c8219181e40dddcaf820545e08283de93 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 9 Oct 2012 15:58:48 +0100 Subject: Rename HTMLTemplateRenderer -> HTMLRenderer, DocuemntingHTMLRenderer -> BrowseableAPIRenderer --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index ccc8f368..4ee10155 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -24,7 +24,7 @@ from django.utils import importlib DEFAULTS = { 'DEFAULT_RENDERERS': ( 'rest_framework.renderers.JSONRenderer', - 'rest_framework.renderers.DocumentingHTMLRenderer', + 'rest_framework.renderers.BrowsableAPIRenderer', ), 'DEFAULT_PARSERS': ( 'rest_framework.parsers.JSONParser', -- cgit v1.2.3 From 5c7f3e23ee54d340652b9e78c4f4731d93124270 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 10 Oct 2012 12:54:40 +0100 Subject: Tidy up APISettings object to not rely on module state --- rest_framework/settings.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 4ee10155..5ebe7ba5 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -21,6 +21,8 @@ from django.conf import settings from django.utils import importlib +USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None) + DEFAULTS = { 'DEFAULT_RENDERERS': ( 'rest_framework.renderers.JSONRenderer', @@ -76,22 +78,19 @@ IMPORT_STRINGS = ( ) -def perform_import(val, setting): +def perform_import(val, setting_name): """ If the given setting is a string import notation, then perform the necessary import or imports. """ - if val is None or not setting in IMPORT_STRINGS: - return val - if isinstance(val, basestring): - return import_from_string(val, setting) + return import_from_string(val, setting_name) elif isinstance(val, (list, tuple)): - return [import_from_string(item, setting) for item in val] + return [import_from_string(item, setting_name) for item in val] return val -def import_from_string(val, setting): +def import_from_string(val, setting_name): """ Attempt to import a class from a string representation. """ @@ -102,7 +101,7 @@ def import_from_string(val, setting): module = importlib.import_module(module_path) return getattr(module, class_name) except: - msg = "Could not import '%s' for API setting '%s'" % (val, setting) + msg = "Could not import '%s' for API setting '%s'" % (val, setting_name) raise ImportError(msg) @@ -117,19 +116,28 @@ class APISettings(object): Any setting with string import paths will be automatically resolved and return the class, rather than the string literal. """ + def __init__(self, user_settings=None, defaults=None, import_strings=None): + self.user_settings = user_settings or {} + self.defaults = defaults or {} + self.import_strings = import_strings or () + def __getattr__(self, attr): - if attr not in DEFAULTS.keys(): + if attr not in self.defaults.keys(): raise AttributeError("Invalid API setting: '%s'" % attr) try: # Check if present in user settings - val = perform_import(settings.REST_FRAMEWORK[attr], attr) - except (AttributeError, KeyError): + val = self.user_settings[attr] + except KeyError: # Fall back to defaults - val = perform_import(DEFAULTS[attr], attr) + val = self.defaults[attr] + + # Coerce import strings into classes + if val and attr in self.import_strings: + val = perform_import(val, attr) # Cache the result setattr(self, attr, val) return val -api_settings = APISettings() +api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) -- cgit v1.2.3 From 9c1fba3483b7e81da0744464dcf23a5f12711de2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 15 Oct 2012 13:27:50 +0100 Subject: Tweak parsers to take parser_context --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 5ebe7ba5..8bbb2f75 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -35,7 +35,7 @@ DEFAULTS = { ), 'DEFAULT_AUTHENTICATION': ( 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.UserBasicAuthentication' + 'rest_framework.authentication.BasicAuthentication' ), 'DEFAULT_PERMISSIONS': (), 'DEFAULT_THROTTLES': (), -- cgit v1.2.3 From fed235dd0135c3eb98bb218a51f01ace5ddd3782 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 17 Oct 2012 23:09:11 +0100 Subject: Make settings consistent with corrosponding view attributes --- rest_framework/settings.py | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 8bbb2f75..3c508294 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -3,11 +3,11 @@ Settings for REST framework are all namespaced in the REST_FRAMEWORK setting. For example your project's `settings.py` file might look like this: REST_FRAMEWORK = { - 'DEFAULT_RENDERERS': ( + 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.YAMLRenderer', ) - 'DEFAULT_PARSERS': ( + 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.YAMLParser', ) @@ -24,30 +24,33 @@ from django.utils import importlib USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None) DEFAULTS = { - 'DEFAULT_RENDERERS': ( + 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.BrowsableAPIRenderer', ), - 'DEFAULT_PARSERS': ( + 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ), - 'DEFAULT_AUTHENTICATION': ( + 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ), - 'DEFAULT_PERMISSIONS': (), - 'DEFAULT_THROTTLES': (), - 'DEFAULT_CONTENT_NEGOTIATION': + 'DEFAULT_PERMISSION_CLASSES': (), + 'DEFAULT_THROTTLE_CLASSES': (), + 'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation', + + 'DEFAULT_MODEL_SERIALIZER_CLASS': + 'rest_framework.serializers.ModelSerializer', + 'DEFAULT_PAGINATION_SERIALIZER_CLASS': + 'rest_framework.pagination.PaginationSerializer', + 'DEFAULT_THROTTLE_RATES': { 'user': None, 'anon': None, }, - - 'MODEL_SERIALIZER': 'rest_framework.serializers.ModelSerializer', - 'PAGINATION_SERIALIZER': 'rest_framework.pagination.PaginationSerializer', 'PAGINATE_BY': None, 'UNAUTHENTICATED_USER': 'django.contrib.auth.models.AnonymousUser', @@ -65,14 +68,14 @@ DEFAULTS = { # List of settings that may be in string import notation. IMPORT_STRINGS = ( - 'DEFAULT_RENDERERS', - 'DEFAULT_PARSERS', - 'DEFAULT_AUTHENTICATION', - 'DEFAULT_PERMISSIONS', - 'DEFAULT_THROTTLES', - 'DEFAULT_CONTENT_NEGOTIATION', - 'MODEL_SERIALIZER', - 'PAGINATION_SERIALIZER', + 'DEFAULT_RENDERER_CLASSES', + 'DEFAULT_PARSER_CLASSES', + 'DEFAULT_AUTHENTICATION_CLASSES', + 'DEFAULT_PERMISSION_CLASSES', + 'DEFAULT_THROTTLE_CLASSES', + 'DEFAULT_CONTENT_NEGOTIATION_CLASS', + 'DEFAULT_MODEL_SERIALIZER_CLASS', + 'DEFAULT_PAGINATION_SERIALIZER_CLASS', 'UNAUTHENTICATED_USER', 'UNAUTHENTICATED_TOKEN', ) @@ -111,7 +114,7 @@ class APISettings(object): For example: from rest_framework.settings import api_settings - print api_settings.DEFAULT_RENDERERS + print api_settings.DEFAULT_RENDERER_CLASSES Any setting with string import paths will be automatically resolved and return the class, rather than the string literal. -- cgit v1.2.3 From d995742afc09ff8d387751a6fe47b9686845740b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 27 Oct 2012 20:04:33 +0100 Subject: Add AllowAny permission --- rest_framework/settings.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'rest_framework/settings.py') diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 3c508294..9c40a214 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -37,11 +37,14 @@ DEFAULTS = { 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.BasicAuthentication' ), - 'DEFAULT_PERMISSION_CLASSES': (), - 'DEFAULT_THROTTLE_CLASSES': (), + 'DEFAULT_PERMISSION_CLASSES': ( + 'rest_framework.permissions.AllowAny', + ), + 'DEFAULT_THROTTLE_CLASSES': ( + ), + 'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'rest_framework.negotiation.DefaultContentNegotiation', - 'DEFAULT_MODEL_SERIALIZER_CLASS': 'rest_framework.serializers.ModelSerializer', 'DEFAULT_PAGINATION_SERIALIZER_CLASS': -- cgit v1.2.3