From 26ac2656e5e0b3d01a67551910113a305d2a2820 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 5 Jan 2015 16:20:15 +0000 Subject: Pass init arguments through to serializer from pagination serializer. Closes #2355. Normally a serializer won't need these arguments on __init__, but if a user has customized __init__ they may expect them to be available. --- rest_framework/pagination.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index f31e5fa4..9c8dda8f 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -37,16 +37,13 @@ class PreviousPageField(serializers.Field): return replace_query_param(url, self.page_field, page) -class DefaultObjectSerializer(serializers.ReadOnlyField): +class DefaultObjectSerializer(serializers.Serializer): """ If no object serializer is specified, then this serializer will be applied as the default. """ - - def __init__(self, source=None, many=None, context=None): - # Note: Swallow context and many kwargs - only required for - # eg. ModelSerializer. - super(DefaultObjectSerializer, self).__init__(source=source) + def to_representation(self, value): + return value class BasePaginationSerializer(serializers.Serializer): @@ -74,10 +71,9 @@ class BasePaginationSerializer(serializers.Serializer): list_serializer_class = serializers.ListSerializer self.fields[results_field] = list_serializer_class( - child=object_serializer(), + child=object_serializer(*args, **kwargs), source='object_list' ) - self.fields[results_field].bind(field_name=results_field, parent=self) class PaginationSerializer(BasePaginationSerializer): -- cgit v1.2.3 From d3b2302588f333b22d5e4aa2be6eca0e944e9494 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 5 Jan 2015 16:31:52 +0000 Subject: Minor docs update. Refs #2375. --- docs/topics/3.0-announcement.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/topics/3.0-announcement.md b/docs/topics/3.0-announcement.md index 68d24782..5dbc5600 100644 --- a/docs/topics/3.0-announcement.md +++ b/docs/topics/3.0-announcement.md @@ -87,12 +87,12 @@ The resulting API changes are further detailed below. #### The `.create()` and `.update()` methods. -The `.restore_object()` method is now replaced with two separate methods, `.create()` and `.update()`. - -These methods also replace the optional `.save_object()` method, which no longer exists. +The `.restore_object()` method is now removed, and we instead have two separate methods, `.create()` and `.update()`. These methods work slightly different to the previous `.restore_object()`. When using the `.create()` and `.update()` methods you should both create *and save* the object instance. This is in contrast to the previous `.restore_object()` behavior that would instantiate the object but not save it. +These methods also replace the optional `.save_object()` method, which no longer exists. + The following example from the tutorial previously used `restore_object()` to handle both creating and updating object instances. def restore_object(self, attrs, instance=None): -- cgit v1.2.3 From 271b638df10c0cf498cbc69847f388e978c4da78 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 6 Jan 2015 11:21:58 +0000 Subject: Update exception docs. Closes #2378. --- docs/api-guide/exceptions.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index 467ad970..993134f7 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -18,7 +18,7 @@ The handled exceptions are: In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error. -By default all error responses will include a key `detail` in the body of the response, but other keys may also be included. +Most error responses will include a key `detail` in the body of the response. For example, the following request: @@ -33,6 +33,16 @@ Might receive an error response indicating that the `DELETE` method is not allow {"detail": "Method 'DELETE' not allowed."} +Validation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the "non_field_errors" key, or whatever string value has been set for the `NON_FIELD_ERRORS_KEY` setting. + +Any example validation error might look like this: + + HTTP/1.1 400 Bad Request + Content-Type: application/json + Content-Length: 94 + + {"amount": ["A valid integer is required."], "description": ["This field may not be blank."]} + ## Custom exception handling You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API. -- cgit v1.2.3 From 07ad0474c0cef8f8e88d299eca9dffbe6d01c10d Mon Sep 17 00:00:00 2001 From: Ryan Gaffney Date: Tue, 6 Jan 2015 14:34:36 -0800 Subject: Fix compatibility comment regarding OrderedDict --- rest_framework/compat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index ba26a3cd..b1f6f2fa 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -36,7 +36,7 @@ def unicode_to_repr(value): # OrderedDict only available in Python 2.7. # This will always be the case in Django 1.7 and above, as these versions # no longer support Python 2.6. -# For Django <= 1.6 and Python 2.6 fall back to OrderedDict. +# For Django <= 1.6 and Python 2.6 fall back to SortedDict. try: from collections import OrderedDict except ImportError: -- cgit v1.2.3 From fe92a2cfee9e3a20e913500802d98a15e8b70780 Mon Sep 17 00:00:00 2001 From: JocelynDelalande Date: Wed, 7 Jan 2015 10:42:11 +0100 Subject: fixed doc : DEFAULT_AUTHENTICATION_CLASSES -> DEFAULT_AUTHENTICATION + It is consistent with docs about DEFAULT_PERMISSION_CLASSES--- docs/api-guide/authentication.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index b04858e3..1222dbf0 100755 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -34,7 +34,7 @@ The value of `request.user` and `request.auth` for unauthenticated requests can ## Setting the authentication scheme -The default authentication schemes may be set globally, using the `DEFAULT_AUTHENTICATION` setting. For example. +The default authentication schemes may be set globally, using the `DEFAULT_AUTHENTICATION_CLASSES` setting. For example. REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( @@ -282,7 +282,7 @@ This authentication class depends on the optional [django-oauth2-provider][djang 'provider.oauth2', ) -Then add `OAuth2Authentication` to your global `DEFAULT_AUTHENTICATION` setting: +Then add `OAuth2Authentication` to your global `DEFAULT_AUTHENTICATION_CLASSES` setting: 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.OAuth2Authentication', -- cgit v1.2.3 From 42f1932b520a90ae6f8e11246a0992e5f8983bd7 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Wed, 7 Jan 2015 19:10:22 +0100 Subject: Release notes for 3.0.3 --- docs/topics/release-notes.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index b9216e36..18a47b71 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -40,6 +40,26 @@ You can determine your currently installed version using `pip freeze`: ## 3.0.x series + +### 3.0.3 + +**Date**: [8th January 2015][3.0.3-milestone]. + +* Fix `MinValueValidator` on `models.DateField`. ([#2369][gh2369]) +* Fix serializer missing context when pagination is used. ([#2355][gh2355]) +* Namespaced router URLs are now supported by the `DefaultRouter`. ([#2351][gh2351]) +* `required=False` allows omission of value for output. ([#2342][gh2342]) +* Use textarea input for `models.TextField`. ([#2340][gh2340]) +* Use custom `ListSerializer` for pagination if required. ([#2331][gh2331], [#2327][gh2327]) +* Better behavior with null and '' for blank HTML fields. ([#2330][gh2330]) +* Ensure fields in `exclude` are model fields. ([#2319][gh2319]) +* Fix `IntegerField` and `max_length` argument incompatibility. ([#2317][gh2317]) +* Fix the YAML encoder for 3.0 serializers. ([#2315][gh2315], [#2283][gh2283]) +* Fix the behavior of empty HTML fields. ([#2311][gh2311], [#1101][gh1101]) +* Fix Metaclass attribute depth ignoring fields attribute. ([#2287][gh2287]) +* Fix `format_suffix_patterns` to work with Django's `i18n_patterns`. ([#2278][gh2278]) +* Ability to customize router URLs for custom actions, using `url_path`. ([#2010][gh2010]) + ### 3.0.2 **Date**: [17th December 2014][3.0.2-milestone]. @@ -729,3 +749,21 @@ For older release notes, [please see the GitHub repo](old-release-notes). [gh2290]: https://github.com/tomchristie/django-rest-framework/issues/2290 [gh2291]: https://github.com/tomchristie/django-rest-framework/issues/2291 [gh2294]: https://github.com/tomchristie/django-rest-framework/issues/2294 + +[gh1101]: https://github.com/tomchristie/django-rest-framework/issues/1101 +[gh2010]: https://github.com/tomchristie/django-rest-framework/issues/2010 +[gh2278]: https://github.com/tomchristie/django-rest-framework/issues/2278 +[gh2283]: https://github.com/tomchristie/django-rest-framework/issues/2283 +[gh2287]: https://github.com/tomchristie/django-rest-framework/issues/2287 +[gh2311]: https://github.com/tomchristie/django-rest-framework/issues/2311 +[gh2315]: https://github.com/tomchristie/django-rest-framework/issues/2315 +[gh2317]: https://github.com/tomchristie/django-rest-framework/issues/2317 +[gh2319]: https://github.com/tomchristie/django-rest-framework/issues/2319 +[gh2327]: https://github.com/tomchristie/django-rest-framework/issues/2327 +[gh2330]: https://github.com/tomchristie/django-rest-framework/issues/2330 +[gh2331]: https://github.com/tomchristie/django-rest-framework/issues/2331 +[gh2340]: https://github.com/tomchristie/django-rest-framework/issues/2340 +[gh2342]: https://github.com/tomchristie/django-rest-framework/issues/2342 +[gh2351]: https://github.com/tomchristie/django-rest-framework/issues/2351 +[gh2355]: https://github.com/tomchristie/django-rest-framework/issues/2355 +[gh2369]: https://github.com/tomchristie/django-rest-framework/issues/2369 -- cgit v1.2.3 From b7015ea8989d67617d276829ccb6a192362ee01f Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Wed, 7 Jan 2015 19:11:17 +0100 Subject: Bumped the version to 3.0.3. --- rest_framework/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index dec89b3e..fdcebb7b 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -8,7 +8,7 @@ ______ _____ _____ _____ __ """ __title__ = 'Django REST framework' -__version__ = '3.0.2' +__version__ = '3.0.3' __author__ = 'Tom Christie' __license__ = 'BSD 2-Clause' __copyright__ = 'Copyright 2011-2015 Tom Christie' -- cgit v1.2.3 From 60f5b5d9f364c383662fb6ae8d210f31e9621c09 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Wed, 7 Jan 2015 19:19:33 +0100 Subject: Make Django REST Framework as zip unsafe. --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 1e54836c..efe39d8d 100755 --- a/setup.py +++ b/setup.py @@ -67,6 +67,7 @@ setup( packages=get_packages('rest_framework'), package_data=get_package_data('rest_framework'), install_requires=[], + zip_safe=False, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', -- cgit v1.2.3 From 1102e22cb407b9069ce3301bd578ba45a775a89e Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Jan 2015 21:02:42 +0000 Subject: Update project-management.md --- docs/topics/project-management.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index f581cabd..037b7182 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -58,6 +58,8 @@ The following template should be used for the description of the issue, and serv #### New members. If you wish to be considered for this or a future date, please comment against this or subsequent issues. + + To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. #### Responsibilities of team members @@ -107,6 +109,8 @@ The following template should be used for the description of the issue, and serv - [ ] Make a release announcement on the [discussion group](https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework). - [ ] Make a release announcement on twitter. - [ ] Close the milestone on GitHub. + + To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. When pushing the release to PyPI ensure that your environment has been installed from our development `requirement.txt`, so that documentation and PyPI installs are consistently being built against a pinned set of packages. -- cgit v1.2.3 From 18cefad3abfa6e6a7bbd278e8d54eef66a1d1e53 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 7 Jan 2015 21:03:50 +0000 Subject: Update project-management.md --- docs/topics/project-management.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index 037b7182..bcc0330e 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -59,7 +59,7 @@ The following template should be used for the description of the issue, and serv If you wish to be considered for this or a future date, please comment against this or subsequent issues. - To modify this process for future releases make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. + To modify this process for future maintenance cycles make a pull request to the [project management](http://www.django-rest-framework.org/topics/project-management/) documentation. #### Responsibilities of team members -- cgit v1.2.3 From e61ef3d39f301bc62323b47af5080877e273c395 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 11:07:47 +0000 Subject: Minor docs updates --- docs/api-guide/filtering.md | 1 + docs/topics/project-management.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 83977048..3eb1538f 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -316,6 +316,7 @@ Typically you'd instead control this by setting `order_by` on the initial querys queryset = User.objects.all() serializer_class = UserSerializer filter_backends = (filters.OrderingFilter,) + ordering_fields = ('username', 'email') ordering = ('username',) The `ordering` attribute may be either a string or a list/tuple of strings. diff --git a/docs/topics/project-management.md b/docs/topics/project-management.md index f581cabd..f052aa83 100644 --- a/docs/topics/project-management.md +++ b/docs/topics/project-management.md @@ -126,6 +126,7 @@ The following issues still need to be addressed: * Ensure `@jamie` has back-up access to the `django-rest-framework.org` domain setup and admin. * Document ownership of the [live example][sandbox] API. * Document ownership of the [mailing list][mailing-list] and IRC channel. +* Document ownership and management of the security mailing list. [bus-factor]: http://en.wikipedia.org/wiki/Bus_factor [un-triaged]: https://github.com/tomchristie/django-rest-framework/issues?q=is%3Aopen+no%3Alabel -- cgit v1.2.3 From b33a6cbff16e5a28a1a696e2ac617303da181720 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:16:58 +0000 Subject: Ensure urlparse is not publically exposed in compat.py - less chance of accidental conflict. --- rest_framework/compat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index b1f6f2fa..971dee9c 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -10,7 +10,7 @@ import inspect from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import force_text -from django.utils.six.moves.urllib import parse as urlparse +from django.utils.six.moves.urllib.parse import urlparse as _urlparse from django.conf import settings from django.utils import six import django @@ -182,7 +182,7 @@ except ImportError: class RequestFactory(DjangoRequestFactory): def generic(self, method, path, data='', content_type='application/octet-stream', **extra): - parsed = urlparse.urlparse(path) + parsed = _urlparse(path) data = force_bytes_or_smart_bytes(data, settings.DEFAULT_CHARSET) r = { 'PATH_INFO': self._get_path(parsed), -- cgit v1.2.3 From f529f83d3c96ca1957d7a8bfc74bd33151cc8d86 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:38:23 +0000 Subject: Minimum Django 1.5 version issue 1.5.6 --- README.md | 2 +- docs/index.md | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8fc11c30..428a2e56 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ There is a live example API for testing purposes, [available here][sandbox]. # Requirements * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.5+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6, 1.7) # Installation diff --git a/docs/index.md b/docs/index.md index 55129df1..a621e3ec 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Some reasons you might want to use REST framework: REST framework requires the following: * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.5+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6, 1.7) The following packages are optional: diff --git a/tox.ini b/tox.ini index 933ee560..ab258f2e 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ setenv = PYTHONDONTWRITEBYTECODE=1 deps = django14: Django==1.4.11 - django15: Django==1.5.5 + django15: Django==1.5.6 django16: Django==1.6.8 django17: Django==1.7.1 djangomaster: https://github.com/django/django/zipball/master -- cgit v1.2.3 From 42c913334b0b4cd731011a07a49ff08aa03d7768 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:51:08 +0000 Subject: Minimum 1.6.x version is 1.6.3 --- README.md | 2 +- docs/index.md | 2 +- tox.ini | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 428a2e56..cf3dc857 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ There is a live example API for testing purposes, [available here][sandbox]. # Requirements * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.6+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7) # Installation diff --git a/docs/index.md b/docs/index.md index a621e3ec..d40f8972 100644 --- a/docs/index.md +++ b/docs/index.md @@ -51,7 +51,7 @@ Some reasons you might want to use REST framework: REST framework requires the following: * Python (2.6.5+, 2.7, 3.2, 3.3, 3.4) -* Django (1.4.11+, 1.5.6+, 1.6, 1.7) +* Django (1.4.11+, 1.5.6+, 1.6.3+, 1.7) The following packages are optional: diff --git a/tox.ini b/tox.ini index ab258f2e..db2b5d13 100644 --- a/tox.ini +++ b/tox.ini @@ -10,10 +10,10 @@ commands = ./runtests.py --fast setenv = PYTHONDONTWRITEBYTECODE=1 deps = - django14: Django==1.4.11 - django15: Django==1.5.6 - django16: Django==1.6.8 - django17: Django==1.7.1 + django14: Django==1.4.11 # Should track minimum supported + django15: Django==1.5.6 # Should track minimum supported + django16: Django==1.6.3 # Should track minimum supported + django17: Django==1.7.3 # Should track maximum supported djangomaster: https://github.com/django/django/zipball/master {py26,py27}-django{14,15,16,17}: django-guardian==1.2.3 {py26,py27}-django{14,15,16}: oauth2==1.5.211 -- cgit v1.2.3 From 08008669886f682ba62c4d377f4d96f64808d4a5 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 14:54:54 +0000 Subject: Fix broken 1.7.3. It's 1.7.2 - 1.7.3 is documented but not yet on PyPI. --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index db2b5d13..4b90c392 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ deps = django14: Django==1.4.11 # Should track minimum supported django15: Django==1.5.6 # Should track minimum supported django16: Django==1.6.3 # Should track minimum supported - django17: Django==1.7.3 # Should track maximum supported + django17: Django==1.7.2 # Should track maximum supported djangomaster: https://github.com/django/django/zipball/master {py26,py27}-django{14,15,16,17}: django-guardian==1.2.3 {py26,py27}-django{14,15,16}: oauth2==1.5.211 -- cgit v1.2.3 From 4d9e7a53565f6301b87999e6bafdb1c2c3c2af3b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 8 Jan 2015 15:38:27 +0000 Subject: Ammend docstring to use python2/3 compatible example. --- rest_framework/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 33f84813..fc6dfecd 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -167,7 +167,7 @@ class APISettings(object): For example: from rest_framework.settings import api_settings - print api_settings.DEFAULT_RENDERER_CLASSES + 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 ef16c546d77d36bbddacf9b66626f7eaf9f4ff17 Mon Sep 17 00:00:00 2001 From: Xavier Ordoquy Date: Thu, 8 Jan 2015 23:29:51 +0100 Subject: Update the release note with latest fixes. Add the link to the 3.0.3 milestone. --- docs/topics/release-notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/topics/release-notes.md b/docs/topics/release-notes.md index 18a47b71..c49dd62c 100644 --- a/docs/topics/release-notes.md +++ b/docs/topics/release-notes.md @@ -59,6 +59,7 @@ You can determine your currently installed version using `pip freeze`: * Fix Metaclass attribute depth ignoring fields attribute. ([#2287][gh2287]) * Fix `format_suffix_patterns` to work with Django's `i18n_patterns`. ([#2278][gh2278]) * Ability to customize router URLs for custom actions, using `url_path`. ([#2010][gh2010]) +* Don't install Django REST Framework as egg. ([#2386][gh2386]) ### 3.0.2 @@ -700,6 +701,7 @@ For older release notes, [please see the GitHub repo](old-release-notes). [3.0.1-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.1+Release%22 [3.0.2-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.2+Release%22 +[3.0.3-milestone]: https://github.com/tomchristie/django-rest-framework/issues?q=milestone%3A%223.0.3+Release%22 [gh2013]: https://github.com/tomchristie/django-rest-framework/issues/2013 @@ -767,3 +769,4 @@ For older release notes, [please see the GitHub repo](old-release-notes). [gh2351]: https://github.com/tomchristie/django-rest-framework/issues/2351 [gh2355]: https://github.com/tomchristie/django-rest-framework/issues/2355 [gh2369]: https://github.com/tomchristie/django-rest-framework/issues/2369 +[gh2386]: https://github.com/tomchristie/django-rest-framework/issues/2386 -- cgit v1.2.3 From 8ccf5bcc0bb3455c0d71a0e0d845ef54489bb28e Mon Sep 17 00:00:00 2001 From: Travis Swientek Date: Fri, 9 Jan 2015 11:36:21 -0800 Subject: Tweaked a few issues in the tutorial documentation. --- docs/tutorial/1-serialization.md | 2 +- docs/tutorial/3-class-based-views.md | 2 +- docs/tutorial/4-authentication-and-permissions.md | 2 +- docs/tutorial/5-relationships-and-hyperlinked-apis.md | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md index 60a3d989..41ff4d07 100644 --- a/docs/tutorial/1-serialization.md +++ b/docs/tutorial/1-serialization.md @@ -191,7 +191,7 @@ Our `SnippetSerializer` class is replicating a lot of information that's also co In the same way that Django provides both `Form` classes and `ModelForm` classes, REST framework includes both `Serializer` classes, and `ModelSerializer` classes. Let's look at refactoring our serializer using the `ModelSerializer` class. -Open the file `snippets/serializers.py` again, and edit the `SnippetSerializer` class. +Open the file `snippets/serializers.py` again, and replace the `SnippetSerializer` class with the following. class SnippetSerializer(serializers.ModelSerializer): class Meta: diff --git a/docs/tutorial/3-class-based-views.md b/docs/tutorial/3-class-based-views.md index 0a9ea3f1..abf82e49 100644 --- a/docs/tutorial/3-class-based-views.md +++ b/docs/tutorial/3-class-based-views.md @@ -64,7 +64,7 @@ That's looking good. Again, it's still pretty similar to the function based vie We'll also need to refactor our `urls.py` slightly now we're using class based views. - from django.conf.urls import patterns, url + from django.conf.urls import url from rest_framework.urlpatterns import format_suffix_patterns from snippets import views diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 592c77e8..887d1e56 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -177,7 +177,7 @@ In the snippets app, create a new file, `permissions.py` # Write permissions are only allowed to the owner of the snippet. return obj.owner == request.user -Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetDetail` class: +Now we can add that custom permission to our snippet instance endpoint, by editing the `permission_classes` property on the `SnippetDetail` view class: permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md index c21efd7f..2841f03e 100644 --- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md +++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md @@ -106,6 +106,8 @@ If we're going to have a hyperlinked API, we need to make sure we name our URL p After adding all those names into our URLconf, our final `snippets/urls.py` file should look something like this: + from django.conf.urls import url, include + # API endpoints urlpatterns = format_suffix_patterns([ url(r'^$', views.api_root), -- cgit v1.2.3 From 50b206d3739660cdf089b0a3f8a5bb21d6970e00 Mon Sep 17 00:00:00 2001 From: Steven Loria Date: Sat, 10 Jan 2015 10:17:37 -0600 Subject: Fix broken links in README --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cf3dc857..74bcaeef 100644 --- a/README.md +++ b/README.md @@ -190,18 +190,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [sandbox]: http://restframework.herokuapp.com/ [index]: http://www.django-rest-framework.org/ -[oauth1-section]: http://www.django-rest-framework.org/api-guide/authentication.html#oauthauthentication -[oauth2-section]: http://www.django-rest-framework.org/api-guide/authentication.html#oauth2authentication -[serializer-section]: http://www.django-rest-framework.org/api-guide/serializers.html#serializers -[modelserializer-section]: http://www.django-rest-framework.org/api-guide/serializers.html#modelserializer -[functionview-section]: http://www.django-rest-framework.org/api-guide/views.html#function-based-views -[generic-views]: http://www.django-rest-framework.org/api-guide/generic-views.html -[viewsets]: http://www.django-rest-framework.org/api-guide/viewsets.html -[routers]: http://www.django-rest-framework.org/api-guide/routers.html -[serializers]: http://www.django-rest-framework.org/api-guide/serializers.html -[authentication]: http://www.django-rest-framework.org/api-guide/authentication.html - -[rest-framework-2-announcement]: http://www.django-rest-framework.org/topics/rest-framework-2-announcement.html +[oauth1-section]: http://www.django-rest-framework.org/api-guide/authentication/#oauthauthentication +[oauth2-section]: http://www.django-rest-framework.org/api-guide/authentication/#oauth2authentication +[serializer-section]: http://www.django-rest-framework.org/api-guide/serializers/#serializers +[modelserializer-section]: http://www.django-rest-framework.org/api-guide/serializers/#modelserializer +[functionview-section]: http://www.django-rest-framework.org/api-guide/views/#function-based-views +[generic-views]: http://www.django-rest-framework.org/api-guide/generic-views/ +[viewsets]: http://www.django-rest-framework.org/api-guide/viewsets/ +[routers]: http://www.django-rest-framework.org/api-guide/routers/ +[serializers]: http://www.django-rest-framework.org/api-guide/serializers/ +[authentication]: http://www.django-rest-framework.org/api-guide/authentication/ + +[rest-framework-2-announcement]: http://www.django-rest-framework.org/topics/rest-framework-2-announcement [2.1.0-notes]: https://groups.google.com/d/topic/django-rest-framework/Vv2M0CMY9bg/discussion [image]: http://www.django-rest-framework.org/img/quickstart.png -- cgit v1.2.3 From d6bff10f9829b3cef1c2773c303b172a8c7ec525 Mon Sep 17 00:00:00 2001 From: Ask Holme Date: Sat, 10 Jan 2015 18:15:21 +0100 Subject: Make FileUploadParser work with standard django API Output from parsers ends up in a Django MergeDict and they exists elements to be dicts - not None--- rest_framework/parsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index 3e3395c0..401856ec 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -277,7 +277,7 @@ class FileUploadParser(BaseParser): for index, handler in enumerate(upload_handlers): file_obj = handler.file_complete(counters[index]) if file_obj: - return DataAndFiles(None, {'file': file_obj}) + return DataAndFiles({}, {'file': file_obj}) raise ParseError("FileUpload parse error - " "none of upload handlers can handle the stream") -- cgit v1.2.3 From d6d08db0dd16f4a4a93b69ecf1c5948f375335b0 Mon Sep 17 00:00:00 2001 From: José Padilla Date: Sun, 11 Jan 2015 10:55:56 -0400 Subject: Fix ident format when using HTTP_X_FORWARDED_FOR If NUM_PROXIES setting is set to None, HTTP_X_FORWARDED_FOR might be used as is, which might contain spaces and cause errors on cache backends like memcached. --- rest_framework/throttling.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index 361dbddf..7dfe2f96 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -35,7 +35,7 @@ class BaseThrottle(object): client_addr = addrs[-min(num_proxies, len(xff))] return client_addr.strip() - return xff if xff else remote_addr + return ''.join(xff.split()) if xff else remote_addr def wait(self): """ @@ -173,12 +173,6 @@ class AnonRateThrottle(SimpleRateThrottle): if request.user.is_authenticated(): return None # Only throttle unauthenticated requests. - ident = request.META.get('HTTP_X_FORWARDED_FOR') - if ident is None: - ident = request.META.get('REMOTE_ADDR') - else: - ident = ''.join(ident.split()) - return self.cache_format % { 'scope': self.scope, 'ident': self.get_ident(request) -- cgit v1.2.3 From cc13ee0577fb3de9602da634ab9c835749da49c4 Mon Sep 17 00:00:00 2001 From: José Padilla Date: Mon, 12 Jan 2015 08:12:24 -0400 Subject: Fix error when NUM_PROXIES is greater than one --- rest_framework/throttling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index 7dfe2f96..0f10136d 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -32,7 +32,7 @@ class BaseThrottle(object): if num_proxies == 0 or xff is None: return remote_addr addrs = xff.split(',') - client_addr = addrs[-min(num_proxies, len(xff))] + client_addr = addrs[-min(num_proxies, len(addrs))] return client_addr.strip() return ''.join(xff.split()) if xff else remote_addr -- cgit v1.2.3 From 7f9a62a5bf6a86c4d0a96e5f00d7e96b22d3337f Mon Sep 17 00:00:00 2001 From: Philip Neustrom Date: Tue, 13 Jan 2015 15:19:52 +0800 Subject: Fix link to `django-rest-framework-filters` (formerly `django-rest-framework-chain`) --- docs/api-guide/filtering.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 07420d84..2b6d5449 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -388,9 +388,9 @@ We could achieve the same behavior by overriding `get_queryset()` on the views, The following third party packages provide additional filter implementations. -## Django REST framework chain +## Django REST framework filters package -The [django-rest-framework-chain package][django-rest-framework-chain] works together with the `DjangoFilterBackend` class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field. +The [django-rest-framework-filters package][django-rest-framework-filters] works together with the `DjangoFilterBackend` class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field. [cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters [django-filter]: https://github.com/alex/django-filter @@ -400,4 +400,4 @@ The [django-rest-framework-chain package][django-rest-framework-chain] works tog [view-permissions-blogpost]: http://blog.nyaruka.com/adding-a-view-permission-to-django-models [nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py [search-django-admin]: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields -[django-rest-framework-chain]: https://github.com/philipn/django-rest-framework-chain +[django-rest-framework-filters]: https://github.com/philipn/django-rest-framework-filters -- cgit v1.2.3 From 4ce4132e08ba7764f120c71eeebdbaefee281689 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 14 Jan 2015 12:56:03 +0000 Subject: Preserve ordering on relationship drop-down choices. Closes #2408. --- rest_framework/relations.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 7b119291..aa0c2def 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -7,6 +7,7 @@ from django.utils import six from django.utils.encoding import smart_text from django.utils.six.moves.urllib import parse as urlparse from django.utils.translation import ugettext_lazy as _ +from rest_framework.compat import OrderedDict from rest_framework.fields import get_attribute, empty, Field from rest_framework.reverse import reverse from rest_framework.utils import html @@ -103,7 +104,7 @@ class RelatedField(Field): @property def choices(self): - return dict([ + return OrderedDict([ ( six.text_type(self.to_representation(item)), six.text_type(item) @@ -364,7 +365,7 @@ class ManyRelatedField(Field): (item, self.child_relation.to_representation(item)) for item in iterable ] - return dict([ + return OrderedDict([ ( six.text_type(item_representation), six.text_type(item) + ' - ' + six.text_type(item_representation) -- cgit v1.2.3 From 7c0d14a6d56a0813a8abf6da53622c323a77bca8 Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 13:55:53 -0800 Subject: Bump pytest-django version to 2.8.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 48b29e61..d5b32bfa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ Django>=1.4.11 # Test requirements -pytest-django==2.6 +pytest-django==2.8.0 pytest==2.5.2 pytest-cov==1.6 flake8==2.2.2 -- cgit v1.2.3 From 00449dc42c11b5795b05885c7a1160dd36501668 Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 13:56:52 -0800 Subject: Bump pytest version to 2.6.4 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d5b32bfa..43e947c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ Django>=1.4.11 # Test requirements pytest-django==2.8.0 -pytest==2.5.2 +pytest==2.6.4 pytest-cov==1.6 flake8==2.2.2 -- cgit v1.2.3 From eb91076886466af9376da753b34883b9dc2a1705 Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 14:45:01 -0800 Subject: Bump pytest-django version in tox.ini to 2.8.0 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 4b90c392..9018b040 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ deps = {py26,py27}-django{14,15,16}: django-oauth-plus==2.2.1 {py26,py27}-django{14,15}: django-oauth2-provider==0.2.3 {py26,py27}-django16: django-oauth2-provider==0.2.4 - pytest-django==2.6.1 + pytest-django==2.8.0 django-filter==0.7 defusedxml==0.3 markdown>=2.1.0 -- cgit v1.2.3 From 1421b057f7ccf496c0e65e89aa3882d614aa7030 Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 14:48:23 -0800 Subject: Bump pytest version in tox.ini to 2.6.4 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 9018b040..f30b44ff 100644 --- a/tox.ini +++ b/tox.ini @@ -28,7 +28,7 @@ deps = [testenv:py27-flake8] deps = - pytest==2.5.2 + pytest==2.6.4 flake8==2.2.2 commands = ./runtests.py --lintonly -- cgit v1.2.3 From a82a4d0a099eea74832ce3d8de376e4dbeb4b266 Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 15:04:50 -0800 Subject: Add Django 1.8 alpha to test matrix --- .travis.yml | 8 ++++++++ tox.ini | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6191e7e2..996c3ae8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,10 @@ env: - TOX_ENV=py26-django15 - TOX_ENV=py27-django14 - TOX_ENV=py26-django14 + - TOX_ENV=py34-django18alpha + - TOX_ENV=py33-django18alpha + - TOX_ENV=py32-django18alpha + - TOX_ENV=py27-django18alpha - TOX_ENV=py34-djangomaster - TOX_ENV=py33-djangomaster - TOX_ENV=py32-djangomaster @@ -29,6 +33,10 @@ env: matrix: fast_finish: true allow_failures: + - env: TOX_ENV=py34-django18alpha + - env: TOX_ENV=py33-django18alpha + - env: TOX_ENV=py32-django18alpha + - env: TOX_ENV=py27-django18alpha - env: TOX_ENV=py34-djangomaster - env: TOX_ENV=py33-djangomaster - env: TOX_ENV=py32-djangomaster diff --git a/tox.ini b/tox.ini index f30b44ff..e43a9234 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ envlist = py27-{flake8,docs}, {py26,py27}-django14, {py26,py27,py32,py33,py34}-django{15,16}, - {py27,py32,py33,py34}-django{17,master} + {py27,py32,py33,py34}-django{17,18alpha,master} [testenv] commands = ./runtests.py --fast @@ -14,6 +14,7 @@ deps = django15: Django==1.5.6 # Should track minimum supported django16: Django==1.6.3 # Should track minimum supported django17: Django==1.7.2 # Should track maximum supported + django18alpha: https://www.djangoproject.com/download/1.8a1/tarball/ djangomaster: https://github.com/django/django/zipball/master {py26,py27}-django{14,15,16,17}: django-guardian==1.2.3 {py26,py27}-django{14,15,16}: oauth2==1.5.211 -- cgit v1.2.3 From b5128ca574d03ea590a198b04043142a3fc7163e Mon Sep 17 00:00:00 2001 From: David Muller Date: Sun, 18 Jan 2015 15:19:11 -0800 Subject: Save objects before assigning them in InheritedModelSerializationTests; Django 1.8 now throws an error when assigning unsaved objects to Foreign Key, GenericForeignKey, and OneToOneFields --- tests/test_multitable_inheritance.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_multitable_inheritance.py b/tests/test_multitable_inheritance.py index e1b40cc7..15627e1d 100644 --- a/tests/test_multitable_inheritance.py +++ b/tests/test_multitable_inheritance.py @@ -48,8 +48,8 @@ class InheritedModelSerializationTests(TestCase): Assert that a model with a onetoone field that is the primary key is not treated like a derived model """ - parent = ParentModel(name1='parent name') - associate = AssociatedModel(name='hello', ref=parent) + parent = ParentModel.objects.create(name1='parent name') + associate = AssociatedModel.objects.create(name='hello', ref=parent) serializer = AssociatedModelSerializer(associate) self.assertEqual(set(serializer.data.keys()), set(['name', 'ref'])) -- cgit v1.2.3 From 5484d570cb8214c776273b45320e7d1c73b85a34 Mon Sep 17 00:00:00 2001 From: Fabien Bochu Date: Mon, 19 Jan 2015 10:57:26 +0100 Subject: Fix timedelta JSON serialization on Python 2.6. --- rest_framework/compat.py | 8 ++++++++ rest_framework/utils/encoders.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 971dee9c..17814136 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -33,6 +33,14 @@ def unicode_to_repr(value): return value +def total_seconds(timedelta): + # TimeDelta.total_seconds() is only available in Python 2.7 + if hasattr(timedelta, 'total_seconds'): + return timedelta.total_seconds() + else: + return (timedelta.days * 86400.0) + float(timedelta.seconds) + (timedelta.microseconds / 1000000.0) + + # OrderedDict only available in Python 2.7. # This will always be the case in Django 1.7 and above, as these versions # no longer support Python 2.6. diff --git a/rest_framework/utils/encoders.py b/rest_framework/utils/encoders.py index 73cbe5d8..104343a4 100644 --- a/rest_framework/utils/encoders.py +++ b/rest_framework/utils/encoders.py @@ -6,7 +6,7 @@ from django.db.models.query import QuerySet from django.utils import six, timezone from django.utils.encoding import force_text from django.utils.functional import Promise -from rest_framework.compat import OrderedDict +from rest_framework.compat import OrderedDict, total_seconds from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList import datetime import decimal @@ -41,7 +41,7 @@ class JSONEncoder(json.JSONEncoder): representation = representation[:12] return representation elif isinstance(obj, datetime.timedelta): - return six.text_type(obj.total_seconds()) + return six.text_type(total_seconds(obj)) elif isinstance(obj, decimal.Decimal): # Serializers will coerce decimals to strings by default. return float(obj) -- cgit v1.2.3 From da1db34a36f6f0cb8722acbbf7c3182e32995ae3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 19 Jan 2015 14:18:02 +0000 Subject: Handle UUID objects in JSONEncoder. Closes #2433. --- rest_framework/utils/encoders.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rest_framework/utils/encoders.py b/rest_framework/utils/encoders.py index 104343a4..bf753271 100644 --- a/rest_framework/utils/encoders.py +++ b/rest_framework/utils/encoders.py @@ -12,6 +12,7 @@ import datetime import decimal import types import json +import uuid class JSONEncoder(json.JSONEncoder): @@ -45,6 +46,8 @@ class JSONEncoder(json.JSONEncoder): elif isinstance(obj, decimal.Decimal): # Serializers will coerce decimals to strings by default. return float(obj) + elif isinstance(obj, uuid.UUID): + return six.text_type(obj) elif isinstance(obj, QuerySet): return tuple(obj) elif hasattr(obj, 'tolist'): -- cgit v1.2.3 From 0dffc46cb71ec868cdbb37187ba03dea7bac4e7a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 19 Jan 2015 14:21:09 +0000 Subject: ReturnDict and ReturnList repr as standard dict/list. Closes #2421. --- rest_framework/utils/serializer_helpers.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 65a04d06..f9960603 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -16,6 +16,9 @@ class ReturnDict(OrderedDict): def copy(self): return ReturnDict(self, serializer=self.serializer) + def __repr__(self): + return dict.__repr__(self) + class ReturnList(list): """ @@ -27,6 +30,9 @@ class ReturnList(list): self.serializer = kwargs.pop('serializer') super(ReturnList, self).__init__(*args, **kwargs) + def __repr__(self): + return list.__repr__(self) + class BoundField(object): """ -- cgit v1.2.3 From af05820b1bfc60ceb7cbb35566588a732938cae2 Mon Sep 17 00:00:00 2001 From: Alexander Dutton Date: Mon, 19 Jan 2015 14:23:13 +0000 Subject: NotImplemented is not an exception `NotImplemented` is a singleton object, not an exception. You should be raising `NotImplementedError` here instead.--- rest_framework/renderers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 634338e9..ba6c9cc1 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -46,7 +46,7 @@ class BaseRenderer(object): render_style = 'text' def render(self, data, accepted_media_type=None, renderer_context=None): - raise NotImplemented('Renderer class requires .render() to be implemented') + raise NotImplementedError('Renderer class requires .render() to be implemented') class JSONRenderer(BaseRenderer): -- cgit v1.2.3 From 46a3eda08d519c6908ecd1b9c2e13e5fdb773b0c Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 19 Jan 2015 14:48:13 +0000 Subject: NotImplemented -> NotImplementedError --- rest_framework/routers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 61f3ccab..827da034 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -65,13 +65,13 @@ class BaseRouter(object): If `base_name` is not specified, attempt to automatically determine it from the viewset. """ - raise NotImplemented('get_default_base_name must be overridden') + raise NotImplementedError('get_default_base_name must be overridden') def get_urls(self): """ Return a list of URL patterns, given the registered viewsets. """ - raise NotImplemented('get_urls must be overridden') + raise NotImplementedError('get_urls must be overridden') @property def urls(self): -- cgit v1.2.3