diff options
| author | Tom Christie | 2014-09-19 14:05:50 +0100 | 
|---|---|---|
| committer | Tom Christie | 2014-09-19 14:05:50 +0100 | 
| commit | 88008c0a687219e3104d548196915b1068536d74 (patch) | |
| tree | 31c21a93d3e11e8ba66e83c96f8947783e8d676e | |
| parent | 6d73b5969a9d415a6d43175e77bc10ba76151e97 (diff) | |
| parent | 1e9ea377e3f0521ec5d9c21527cfad3c7626baaa (diff) | |
| download | django-rest-framework-88008c0a687219e3104d548196915b1068536d74.tar.bz2 | |
Merge branch 'master' into version-3.0
| -rw-r--r-- | docs/api-guide/exceptions.md | 2 | ||||
| -rw-r--r-- | docs/api-guide/renderers.md | 12 | ||||
| -rw-r--r-- | docs/index.md | 4 | ||||
| -rw-r--r-- | docs/template.html | 1 | ||||
| -rw-r--r-- | docs/topics/third-party-resources.md | 91 | ||||
| -rwxr-xr-x | mkdocs.py | 1 | ||||
| -rw-r--r-- | rest_framework/authtoken/migrations/0001_initial.py | 7 | ||||
| -rw-r--r-- | rest_framework/authtoken/serializers.py | 2 | ||||
| -rw-r--r-- | rest_framework/routers.py | 12 | ||||
| -rw-r--r-- | rest_framework/viewsets.py | 3 | ||||
| -rw-r--r-- | tests/test_routers.py | 18 | 
11 files changed, 142 insertions, 11 deletions
| diff --git a/docs/api-guide/exceptions.md b/docs/api-guide/exceptions.md index 66e18173..e61dcfa9 100644 --- a/docs/api-guide/exceptions.md +++ b/docs/api-guide/exceptions.md @@ -84,7 +84,7 @@ Note that the exception handler will only be called for responses generated by r  **Signature:** `APIException()` -The **base class** for all exceptions raised inside REST framework. +The **base class** for all exceptions raised inside an `APIView` class or `@api_view`.  To provide a custom exception, subclass `APIException` and set the `.status_code` and `.default_detail` properties on the class. diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index b1adf31f..2e1c892f 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -425,6 +425,11 @@ Comma-separated values are a plain-text tabular data format, that can be easily  [djangorestframework-camel-case] provides camel case JSON renderers and parsers for REST framework.  This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names.  It is maintained by [Vitaly Babiy][vbabiy]. +## Pandas (CSV, Excel, PNG) + +[Django REST Pandas] provides a serializer and renderers that support additional data processing and output via the [Pandas] DataFrame API.  Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both `.xls` and `.xlsx`), and a number of [other formats]. It is maintained by [S. Andrew Sheppard][sheppard] as part of the [wq Project][wq]. + +  [cite]: https://docs.djangoproject.com/en/dev/ref/template-response/#the-rendering-process  [conneg]: content-negotiation.md  [browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers @@ -447,4 +452,9 @@ Comma-separated values are a plain-text tabular data format, that can be easily  [ultrajson]: https://github.com/esnme/ultrajson  [hzy]: https://github.com/hzy  [drf-ujson-renderer]: https://github.com/gizmag/drf-ujson-renderer -[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
\ No newline at end of file +[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case +[Django REST Pandas]: https://github.com/wq/django-rest-pandas +[Pandas]: http://pandas.pydata.org/ +[other formats]: https://github.com/wq/django-rest-pandas#supported-formats +[sheppard]: https://github.com/sheppard +[wq]: https://github.com/wq diff --git a/docs/index.md b/docs/index.md index 1888bfe4..6dcb962f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -195,6 +195,7 @@ General guides to using REST framework.  * [Browser enhancements][browser-enhancements]  * [The Browsable API][browsableapi]  * [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas] +* [Third Party Resources][third-party-resources]  * [Contributing to REST framework][contributing]  * [2.0 Announcement][rest-framework-2-announcement]  * [2.2 Announcement][2.2-announcement] @@ -312,11 +313,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  [browsableapi]: topics/browsable-api.md  [rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md  [contributing]: topics/contributing.md +[third-party-resources]: topics/third-party-resources.md  [rest-framework-2-announcement]: topics/rest-framework-2-announcement.md  [2.2-announcement]: topics/2.2-announcement.md  [2.3-announcement]: topics/2.3-announcement.md  [2.4-announcement]: topics/2.4-announcement.md -[kickstarter-announcement]: topics/kickstarter-announcement.md  +[kickstarter-announcement]: topics/kickstarter-announcement.md  [release-notes]: topics/release-notes.md  [credits]: topics/credits.md diff --git a/docs/template.html b/docs/template.html index 19542bfe..bb3ae221 100644 --- a/docs/template.html +++ b/docs/template.html @@ -117,6 +117,7 @@ a.fusion-poweredby {                    <li><a href="{{ base_url }}/topics/browser-enhancements{{ suffix }}">Browser enhancements</a></li>                    <li><a href="{{ base_url }}/topics/browsable-api{{ suffix }}">The Browsable API</a></li>                    <li><a href="{{ base_url }}/topics/rest-hypermedia-hateoas{{ suffix }}">REST, Hypermedia & HATEOAS</a></li> +                  <li><a href="{{ base_url }}/topics/third-party-resources{{ suffix }}">Third Party Resources</a></li>                    <li><a href="{{ base_url }}/topics/contributing{{ suffix }}">Contributing to REST framework</a></li>                    <li><a href="{{ base_url }}/topics/rest-framework-2-announcement{{ suffix }}">2.0 Announcement</a></li>                    <li><a href="{{ base_url }}/topics/2.2-announcement{{ suffix }}">2.2 Announcement</a></li> diff --git a/docs/topics/third-party-resources.md b/docs/topics/third-party-resources.md new file mode 100644 index 00000000..1ca91742 --- /dev/null +++ b/docs/topics/third-party-resources.md @@ -0,0 +1,91 @@ +# Third Party Resources + +Django REST Framework has a growing community of developers, packages, and resources. + +Check out a grid detailing all the packages and ecosystem around Django REST Framework at [Django Packages](https://www.djangopackages.com/grids/g/django-rest-framework/). + +To submit new content, [open an issue](https://github.com/tomchristie/django-rest-framework/issues/new) or [create a pull request](https://github.com/tomchristie/django-rest-framework/). + +## Libraries and Extensions + +### Authentication + +* [djangorestframework-digestauth](https://github.com/juanriaza/django-rest-framework-digestauth) - Provides Digest Access Authentication support. +* [django-oauth-toolkit](https://github.com/evonove/django-oauth-toolkit) - Provides OAuth 2.0 support. +* [doac](https://github.com/Rediker-Software/doac) - Provides OAuth 2.0 support. +* [djangorestframework-jwt](https://github.com/GetBlimp/django-rest-framework-jwt) - Provides JSON Web Token Authentication support. +* [hawkrest](https://github.com/kumar303/hawkrest) - Provides Hawk HTTP Authorization. +* [djangorestframework-httpsignature](https://github.com/etoccalino/django-rest-framework-httpsignature) - Provides an easy to use HTTP Signature Authentication mechanism. + +### Permissions + +* [drf-any-permissions](https://github.com/kevin-brown/drf-any-permissions) - Provides alternative permission handling. +* [djangorestframework-composed-permissions](https://github.com/niwibe/djangorestframework-composed-permissions) - Provides a simple way to define complex permissions. +* [rest_condition](https://github.com/caxap/rest_condition) - Another extension for building complex permissions in a simple and convenient way. + +### Serializers + +* [django-rest-framework-mongoengine](https://github.com/umutbozkurt/django-rest-framework-mongoengine) - Serializer class that supports using MongoDB as the storage layer for Django REST framework. +* [djangorestframework-gis](https://github.com/djangonauts/django-rest-framework-gis) - Geographic add-ons +* [djangorestframework-hstore](https://github.com/djangonauts/django-rest-framework-hstore) - Serializer class to support django-hstore DictionaryField model field and its schema-mode feature. + +### Serializer fields + +* [drf-compound-fields](https://github.com/estebistec/drf-compound-fields) - Provides "compound" serializer fields, such as lists of simple values. +* [django-extra-fields](https://github.com/Hipo/drf-extra-fields) - Provides extra serializer fields. + +### Views + +* [djangorestframework-bulk](https://github.com/miki725/django-rest-framework-bulk) - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests. + +### Routers + +* [drf-nested-routers](https://github.com/alanjds/drf-nested-routers) - Provides routers and relationship fields for working with nested resources. +* [wq.db.rest](http://wq.io/docs/about-rest) - Provides an admin-style model registration API with reasonable default URLs and viewsets. + +### Parsers + +* [djangorestframework-msgpack](https://github.com/juanriaza/django-rest-framework-msgpack) - Provides MessagePack renderer and parser support. +* [djangorestframework-camel-case](https://github.com/vbabiy/djangorestframework-camel-case) - Provides camel case JSON renderers and parsers. + +### Renderers + +* [djangorestframework-csv](https://github.com/mjumbewu/django-rest-framework-csv) - Provides CSV renderer support. +* [drf_ujson](https://github.com/gizmag/drf-ujson-renderer) - Implements JSON rendering using the UJSON package. +* [Django REST Pandas](https://github.com/wq/django-rest-pandas) - Pandas DataFrame-powered renderers including Excel, CSV, and SVG formats. + +### Filtering + +* [djangorestframework-chain](https://github.com/philipn/django-rest-framework-chain) - Allows arbitrary chaining of both relations and lookup filters. + +### Misc + +* [djangorestrelationalhyperlink](https://github.com/fredkingham/django_rest_model_hyperlink_serializers_project) - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer. +* [django-rest-swagger](https://github.com/marcgibbons/django-rest-swagger) - An API documentation generator for Swagger UI. +* [django-rest-framework-proxy ](https://github.com/eofs/django-rest-framework-proxy) - Proxy to redirect incoming request to another API server. +* [gaiarestframework](https://github.com/AppsFuel/gaiarestframework) - Utils for django-rest-framewok +* [drf-extensions](https://github.com/chibisov/drf-extensions) - A collection of custom extensions +* [ember-data-django-rest-adapter](https://github.com/toranb/ember-data-django-rest-adapter) - An ember-data adapter + +## Tutorials + +* [Beginner's Guide to the Django Rest Framework](http://code.tutsplus.com/tutorials/beginners-guide-to-the-django-rest-framework--cms-19786) +* [Getting Started with Django Rest Framework and AngularJS](http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html) +* [End to end web app with Django-Rest-Framework & AngularJS](http://blog.mourafiq.com/post/55034504632/end-to-end-web-app-with-django-rest-framework) +* [Start Your API - django-rest-framework part 1](https://godjango.com/41-start-your-api-django-rest-framework-part-1/) +* [Permissions & Authentication - django-rest-framework part 2](https://godjango.com/43-permissions-authentication-django-rest-framework-part-2/) +* [ViewSets and Routers - django-rest-framework part 3](https://godjango.com/45-viewsets-and-routers-django-rest-framework-part-3/) +* [Django Rest Framework User Endpoint](http://richardtier.com/2014/02/25/django-rest-framework-user-endpoint/) +* [Check credentials using Django Rest Framework](http://richardtier.com/2014/03/06/110/) + +## Videos + +* [Ember and Django Part 1 (Video)](http://www.neckbeardrepublic.com/screencasts/ember-and-django-part-1) +* [Django Rest Framework Part 1 (Video)](http://www.neckbeardrepublic.com/screencasts/django-rest-framework-part-1) +* [Pyowa July 2013 - Django Rest Framework (Video)](http://www.youtube.com/watch?v=E1ZrehVxpBo) +* [django-rest-framework and angularjs (Video)](http://www.youtube.com/watch?v=Q8FRBGTJ020) + +## Articles + +* [Web API performance: profiling Django REST framework](http://dabapps.com/blog/api-performance-profiling-django-rest-framework/) +* [API Development with Django and Django REST Framework](https://bnotions.com/api-development-with-django-and-django-rest-framework/) @@ -76,6 +76,7 @@ path_list = [      'topics/browser-enhancements.md',      'topics/browsable-api.md',      'topics/rest-hypermedia-hateoas.md', +    'topics/third-party-resources.md',      'topics/contributing.md',      'topics/rest-framework-2-announcement.md',      'topics/2.2-announcement.md', diff --git a/rest_framework/authtoken/migrations/0001_initial.py b/rest_framework/authtoken/migrations/0001_initial.py index 2e5d6b47..769f6202 100644 --- a/rest_framework/authtoken/migrations/0001_initial.py +++ b/rest_framework/authtoken/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# encoding: utf8 +# -*- coding: utf-8 -*-  from __future__ import unicode_literals  from django.db import models, migrations @@ -15,12 +15,11 @@ class Migration(migrations.Migration):          migrations.CreateModel(              name='Token',              fields=[ -                ('key', models.CharField(max_length=40, serialize=False, primary_key=True)), -                ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, to_field='id')), +                ('key', models.CharField(primary_key=True, serialize=False, max_length=40)),                  ('created', models.DateTimeField(auto_now_add=True)), +                ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='auth_token')),              ],              options={ -                'abstract': False,              },              bases=(models.Model,),          ), diff --git a/rest_framework/authtoken/serializers.py b/rest_framework/authtoken/serializers.py index edeae857..c2c456de 100644 --- a/rest_framework/authtoken/serializers.py +++ b/rest_framework/authtoken/serializers.py @@ -20,7 +20,7 @@ class AuthTokenSerializer(serializers.Serializer):                      msg = _('User account is disabled.')                      raise serializers.ValidationError(msg)              else: -                msg = _('Unable to login with provided credentials.') +                msg = _('Unable to log in with provided credentials.')                  raise serializers.ValidationError(msg)          else:              msg = _('Must include "username" and "password"') diff --git a/rest_framework/routers.py b/rest_framework/routers.py index 8f1ab6fa..f2d06211 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -19,6 +19,7 @@ import itertools  from collections import namedtuple  from django.conf.urls import patterns, url  from django.core.exceptions import ImproperlyConfigured +from django.core.urlresolvers import NoReverseMatch  from rest_framework import views  from rest_framework.response import Response  from rest_framework.reverse import reverse @@ -287,7 +288,16 @@ class DefaultRouter(SimpleRouter):              def get(self, request, *args, **kwargs):                  ret = {}                  for key, url_name in api_root_dict.items(): -                    ret[key] = reverse(url_name, request=request, format=kwargs.get('format', None)) +                    try: +                        ret[key] = reverse( +                            url_name, +                            request=request, +                            format=kwargs.get('format', None) +                        ) +                    except NoReverseMatch: +                        # Don't bail out if eg. no list routes exist, only detail routes. +                        continue +                  return Response(ret)          return APIRoot.as_view() diff --git a/rest_framework/viewsets.py b/rest_framework/viewsets.py index bb5b304e..84b4bd8d 100644 --- a/rest_framework/viewsets.py +++ b/rest_framework/viewsets.py @@ -20,6 +20,7 @@ from __future__ import unicode_literals  from functools import update_wrapper  from django.utils.decorators import classonlymethod +from django.views.decorators.csrf import csrf_exempt  from rest_framework import views, generics, mixins @@ -89,7 +90,7 @@ class ViewSetMixin(object):          # resolved URL.          view.cls = cls          view.suffix = initkwargs.get('suffix', None) -        return view +        return csrf_exempt(view)      def initialize_request(self, request, *args, **kargs):          """ diff --git a/tests/test_routers.py b/tests/test_routers.py index c2d595f7..34306146 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -3,7 +3,7 @@ from django.conf.urls import patterns, url, include  from django.db import models  from django.test import TestCase  from django.core.exceptions import ImproperlyConfigured -from rest_framework import serializers, viewsets, permissions +from rest_framework import serializers, viewsets, mixins, permissions  from rest_framework.decorators import detail_route, list_route  from rest_framework.response import Response  from rest_framework.routers import SimpleRouter, DefaultRouter @@ -285,3 +285,19 @@ class TestDynamicListAndDetailRouter(TestCase):              else:                  method_map = 'get'              self.assertEqual(route.mapping[method_map], endpoint) + + +class TestRootWithAListlessViewset(TestCase): +    def setUp(self): +        class NoteViewSet(mixins.RetrieveModelMixin, +                          viewsets.GenericViewSet): +            model = RouterTestModel + +        self.router = DefaultRouter() +        self.router.register(r'notes', NoteViewSet) +        self.view = self.router.urls[0].callback + +    def test_api_root(self): +        request = factory.get('/') +        response = self.view(request) +        self.assertEqual(response.data, {}) | 
