mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-02 20:54:42 +03:00
Merge branch 'master' into version-3.0
This commit is contained in:
commit
88008c0a68
|
@ -84,7 +84,7 @@ Note that the exception handler will only be called for responses generated by r
|
||||||
|
|
||||||
**Signature:** `APIException()`
|
**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.
|
To provide a custom exception, subclass `APIException` and set the `.status_code` and `.default_detail` properties on the class.
|
||||||
|
|
||||||
|
|
|
@ -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].
|
[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
|
[cite]: https://docs.djangoproject.com/en/dev/ref/template-response/#the-rendering-process
|
||||||
[conneg]: content-negotiation.md
|
[conneg]: content-negotiation.md
|
||||||
[browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers
|
[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
|
[ultrajson]: https://github.com/esnme/ultrajson
|
||||||
[hzy]: https://github.com/hzy
|
[hzy]: https://github.com/hzy
|
||||||
[drf-ujson-renderer]: https://github.com/gizmag/drf-ujson-renderer
|
[drf-ujson-renderer]: https://github.com/gizmag/drf-ujson-renderer
|
||||||
[djangorestframework-camel-case]: https://github.com/vbabiy/djangorestframework-camel-case
|
[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
|
||||||
|
|
|
@ -195,6 +195,7 @@ General guides to using REST framework.
|
||||||
* [Browser enhancements][browser-enhancements]
|
* [Browser enhancements][browser-enhancements]
|
||||||
* [The Browsable API][browsableapi]
|
* [The Browsable API][browsableapi]
|
||||||
* [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas]
|
* [REST, Hypermedia & HATEOAS][rest-hypermedia-hateoas]
|
||||||
|
* [Third Party Resources][third-party-resources]
|
||||||
* [Contributing to REST framework][contributing]
|
* [Contributing to REST framework][contributing]
|
||||||
* [2.0 Announcement][rest-framework-2-announcement]
|
* [2.0 Announcement][rest-framework-2-announcement]
|
||||||
* [2.2 Announcement][2.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
|
[browsableapi]: topics/browsable-api.md
|
||||||
[rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md
|
[rest-hypermedia-hateoas]: topics/rest-hypermedia-hateoas.md
|
||||||
[contributing]: topics/contributing.md
|
[contributing]: topics/contributing.md
|
||||||
|
[third-party-resources]: topics/third-party-resources.md
|
||||||
[rest-framework-2-announcement]: topics/rest-framework-2-announcement.md
|
[rest-framework-2-announcement]: topics/rest-framework-2-announcement.md
|
||||||
[2.2-announcement]: topics/2.2-announcement.md
|
[2.2-announcement]: topics/2.2-announcement.md
|
||||||
[2.3-announcement]: topics/2.3-announcement.md
|
[2.3-announcement]: topics/2.3-announcement.md
|
||||||
[2.4-announcement]: topics/2.4-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
|
[release-notes]: topics/release-notes.md
|
||||||
[credits]: topics/credits.md
|
[credits]: topics/credits.md
|
||||||
|
|
||||||
|
|
|
@ -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/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/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/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/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/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>
|
<li><a href="{{ base_url }}/topics/2.2-announcement{{ suffix }}">2.2 Announcement</a></li>
|
||||||
|
|
91
docs/topics/third-party-resources.md
Normal file
91
docs/topics/third-party-resources.md
Normal file
|
@ -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/browser-enhancements.md',
|
||||||
'topics/browsable-api.md',
|
'topics/browsable-api.md',
|
||||||
'topics/rest-hypermedia-hateoas.md',
|
'topics/rest-hypermedia-hateoas.md',
|
||||||
|
'topics/third-party-resources.md',
|
||||||
'topics/contributing.md',
|
'topics/contributing.md',
|
||||||
'topics/rest-framework-2-announcement.md',
|
'topics/rest-framework-2-announcement.md',
|
||||||
'topics/2.2-announcement.md',
|
'topics/2.2-announcement.md',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# encoding: utf8
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
@ -15,12 +15,11 @@ class Migration(migrations.Migration):
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Token',
|
name='Token',
|
||||||
fields=[
|
fields=[
|
||||||
('key', models.CharField(max_length=40, serialize=False, primary_key=True)),
|
('key', models.CharField(primary_key=True, serialize=False, max_length=40)),
|
||||||
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, to_field='id')),
|
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
('created', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='auth_token')),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'abstract': False,
|
|
||||||
},
|
},
|
||||||
bases=(models.Model,),
|
bases=(models.Model,),
|
||||||
),
|
),
|
||||||
|
|
|
@ -20,7 +20,7 @@ class AuthTokenSerializer(serializers.Serializer):
|
||||||
msg = _('User account is disabled.')
|
msg = _('User account is disabled.')
|
||||||
raise serializers.ValidationError(msg)
|
raise serializers.ValidationError(msg)
|
||||||
else:
|
else:
|
||||||
msg = _('Unable to login with provided credentials.')
|
msg = _('Unable to log in with provided credentials.')
|
||||||
raise serializers.ValidationError(msg)
|
raise serializers.ValidationError(msg)
|
||||||
else:
|
else:
|
||||||
msg = _('Must include "username" and "password"')
|
msg = _('Must include "username" and "password"')
|
||||||
|
|
|
@ -19,6 +19,7 @@ import itertools
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from django.conf.urls import patterns, url
|
from django.conf.urls import patterns, url
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.core.urlresolvers import NoReverseMatch
|
||||||
from rest_framework import views
|
from rest_framework import views
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.reverse import reverse
|
from rest_framework.reverse import reverse
|
||||||
|
@ -287,7 +288,16 @@ class DefaultRouter(SimpleRouter):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
ret = {}
|
ret = {}
|
||||||
for key, url_name in api_root_dict.items():
|
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 Response(ret)
|
||||||
|
|
||||||
return APIRoot.as_view()
|
return APIRoot.as_view()
|
||||||
|
|
|
@ -20,6 +20,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
from django.utils.decorators import classonlymethod
|
from django.utils.decorators import classonlymethod
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from rest_framework import views, generics, mixins
|
from rest_framework import views, generics, mixins
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,7 +90,7 @@ class ViewSetMixin(object):
|
||||||
# resolved URL.
|
# resolved URL.
|
||||||
view.cls = cls
|
view.cls = cls
|
||||||
view.suffix = initkwargs.get('suffix', None)
|
view.suffix = initkwargs.get('suffix', None)
|
||||||
return view
|
return csrf_exempt(view)
|
||||||
|
|
||||||
def initialize_request(self, request, *args, **kargs):
|
def initialize_request(self, request, *args, **kargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.conf.urls import patterns, url, include
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
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.decorators import detail_route, list_route
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.routers import SimpleRouter, DefaultRouter
|
from rest_framework.routers import SimpleRouter, DefaultRouter
|
||||||
|
@ -285,3 +285,19 @@ class TestDynamicListAndDetailRouter(TestCase):
|
||||||
else:
|
else:
|
||||||
method_map = 'get'
|
method_map = 'get'
|
||||||
self.assertEqual(route.mapping[method_map], endpoint)
|
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, {})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user