Skip to content

Commit 8ea7d6b

Browse files
committed
Merge remote-tracking branch 'origin/master' into markdown-compat
Conflicts: requirements/requirements-optionals.txt
2 parents f308900 + 50749c4 commit 8ea7d6b

File tree

159 files changed

+8352
-2709
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+8352
-2709
lines changed

.isort.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
skip=.tox
33
atomic=true
44
multi_line_output=5
5+
known_standard_library=types
56
known_third_party=pytest,django
67
known_first_party=rest_framework

.tx/config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[main]
22
host = https://www.transifex.com
3+
lang_map = sr@latin:sr_Latn, zh-Hans:zh_Hans, zh-Hant:zh_Hant
34

45
[django-rest-framework.djangopo]
56
file_filter = rest_framework/locale/<lang>/LC_MESSAGES/django.po

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# License
22

3-
Copyright (c) 2011-2015, Tom Christie
3+
Copyright (c) 2011-2016, Tom Christie
44
All rights reserved.
55

66
Redistribution and use in source and binary forms, with or without

docs/api-guide/authentication.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@ The `curl` command line tool may be useful for testing token authenticated APIs.
165165

166166
#### Generating Tokens
167167

168+
##### By using signals
169+
168170
If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal.
169171

170172
from django.conf import settings
@@ -187,6 +189,8 @@ If you've already created some users, you can generate tokens for all existing u
187189
for user in User.objects.all():
188190
Token.objects.get_or_create(user=user)
189191

192+
##### By exposing an api endpoint
193+
190194
When using `TokenAuthentication`, you may want to provide a mechanism for clients to obtain a token given the username and password. REST framework provides a built-in view to provide this behavior. To use it, add the `obtain_auth_token` view to your URLconf:
191195

192196
from rest_framework.authtoken import views
@@ -202,6 +206,17 @@ The `obtain_auth_token` view will return a JSON response when valid `username` a
202206

203207
Note that the default `obtain_auth_token` view explicitly uses JSON requests and responses, rather than using default renderer and parser classes in your settings. If you need a customized version of the `obtain_auth_token` view, you can do so by overriding the `ObtainAuthToken` view class, and using that in your url conf instead.
204208

209+
##### With Django admin
210+
211+
It is also possible to create Tokens manually through admin interface. In case you are using a large user base, we recommend that you monkey patch the `TokenAdmin` class to customize it to your needs, more specifically by declaring the `user` field as `raw_field`.
212+
213+
`your_app/admin.py`:
214+
215+
from rest_framework.authtoken.admin import TokenAdmin
216+
217+
TokenAdmin.raw_id_fields = ('user',)
218+
219+
205220
#### Schema migrations
206221

207222
The `rest_framework.authtoken` app includes both Django native migrations (for Django versions >1.7) and South migrations (for Django versions <1.7) that will create the authtoken table.

docs/api-guide/filtering.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,11 @@ To use REST framework's `DjangoFilterBackend`, first install `django-filter`.
145145

146146
pip install django-filter
147147

148-
If you are using the browsable API or admin API you may also want to install `crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.
148+
If you are using the browsable API or admin API you may also want to install `django-crispy-forms`, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.
149149

150150
pip install django-crispy-forms
151151

152-
With crispy forms installed, the browsable API will present a filtering control for `DjangoFilterBackend`, like so:
152+
With crispy forms installed and added to Django's `INSTALLED_APPS`, the browsable API will present a filtering control for `DjangoFilterBackend`, like so:
153153

154154
![Django Filter](../img/django-filter.png)
155155

@@ -177,7 +177,7 @@ For more advanced filtering requirements you can specify a `FilterSet` class tha
177177
from rest_framework import filters
178178
from rest_framework import generics
179179

180-
class ProductFilter(django_filters.FilterSet):
180+
class ProductFilter(filters.FilterSet):
181181
min_price = django_filters.NumberFilter(name="price", lookup_type='gte')
182182
max_price = django_filters.NumberFilter(name="price", lookup_type='lte')
183183
class Meta:
@@ -199,12 +199,12 @@ You can also span relationships using `django-filter`, let's assume that each
199199
product has foreign key to `Manufacturer` model, so we create filter that
200200
filters using `Manufacturer` name. For example:
201201

202-
import django_filters
203202
from myapp.models import Product
204203
from myapp.serializers import ProductSerializer
204+
from rest_framework import filters
205205
from rest_framework import generics
206206

207-
class ProductFilter(django_filters.FilterSet):
207+
class ProductFilter(filters.FilterSet):
208208
class Meta:
209209
model = Product
210210
fields = ['category', 'in_stock', 'manufacturer__name']
@@ -218,9 +218,10 @@ This is nice, but it exposes the Django's double underscore convention as part o
218218
import django_filters
219219
from myapp.models import Product
220220
from myapp.serializers import ProductSerializer
221+
from rest_framework import filters
221222
from rest_framework import generics
222223

223-
class ProductFilter(django_filters.FilterSet):
224+
class ProductFilter(filters.FilterSet):
224225
manufacturer = django_filters.CharFilter(name="manufacturer__name")
225226

226227
class Meta:

docs/api-guide/generic-views.md

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,6 @@ For more complex cases you might also want to override various methods on the vi
3535
serializer_class = UserSerializer
3636
permission_classes = (IsAdminUser,)
3737

38-
def get_paginate_by(self):
39-
"""
40-
Use smaller pagination for HTML representations.
41-
"""
42-
if self.request.accepted_renderer.format == 'html':
43-
return 20
44-
return 100
45-
4638
def list(self, request):
4739
# Note the use of `get_queryset()` instead of `self.queryset`
4840
queryset = self.get_queryset()
@@ -125,22 +117,22 @@ For example:
125117
Note that if your API doesn't include any object level permissions, you may optionally exclude the `self.check_object_permissions`, and simply return the object from the `get_object_or_404` lookup.
126118

127119
#### `filter_queryset(self, queryset)`
128-
120+
129121
Given a queryset, filter it with whichever filter backends are in use, returning a new queryset.
130-
122+
131123
For example:
132-
124+
133125
def filter_queryset(self, queryset):
134126
filter_backends = (CategoryFilter,)
135-
127+
136128
if 'geo_route' in self.request.query_params:
137129
filter_backends = (GeoRouteFilter, CategoryFilter)
138130
elif 'geo_point' in self.request.query_params:
139131
filter_backends = (GeoPointFilter, CategoryFilter)
140-
132+
141133
for backend in list(filter_backends):
142134
queryset = backend().filter_queryset(self.request, queryset, view=self)
143-
135+
144136
return queryset
145137

146138
#### `get_serializer_class(self)`
@@ -156,19 +148,6 @@ For example:
156148
return FullAccountSerializer
157149
return BasicAccountSerializer
158150

159-
#### `get_paginate_by(self)`
160-
161-
Returns the page size to use with pagination. By default this uses the `paginate_by` attribute, and may be overridden by the client if the `paginate_by_param` attribute is set.
162-
163-
You may want to override this method to provide more complex behavior, such as modifying page sizes based on the media type of the response.
164-
165-
For example:
166-
167-
def get_paginate_by(self):
168-
if self.request.accepted_renderer.format == 'html':
169-
return 20
170-
return 100
171-
172151
**Save and deletion hooks**:
173152

174153
The following methods are provided by the mixin classes, and provide easy overriding of the object save or deletion behavior.
@@ -416,5 +395,3 @@ The [django-rest-framework-bulk package][django-rest-framework-bulk] implements
416395
[DestroyModelMixin]: #destroymodelmixin
417396
[django-rest-framework-bulk]: https://github.com/miki725/django-rest-framework-bulk
418397
[django-rest-multiple-models]: https://github.com/Axiologue/DjangoRestMultipleModels
419-
420-

docs/api-guide/pagination.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ The built-in styles currently all use links included as part of the content of t
1717

1818
Pagination is only performed automatically if you're using the generic views or viewsets. If you're using a regular `APIView`, you'll need to call into the pagination API yourself to ensure you return a paginated response. See the source code for the `mixins.ListModelMixin` and `generics.GenericAPIView` classes for an example.
1919

20+
Pagination can be turned off by setting the pagination class to `None`.
21+
2022
## Setting the pagination style
2123

2224
The default pagination style may be set globally, using the `DEFAULT_PAGINATION_CLASS` settings key. For example, to use the built-in limit/offset pagination, you would do:
@@ -95,6 +97,7 @@ The `PageNumberPagination` class includes a number of attributes that may be ove
9597

9698
To set these attributes you should override the `PageNumberPagination` class, and then enable your custom pagination class as above.
9799

100+
* `django_paginator_class` - The Django Paginator class to use. Default is `django.core.paginator.Paginator`, which should be fine for most use cases.
98101
* `page_size` - A numeric value indicating the page size. If set, this overrides the `PAGE_SIZE` setting. Defaults to the same value as the `PAGE_SIZE` settings key.
99102
* `page_query_param` - A string value indicating the name of the query parameter to use for the pagination control.
100103
* `page_size_query_param` - If set, this is a string value indicating the name of a query parameter that allows the client to set the page size on a per-request basis. Defaults to `None`, indicating that the client may not control the requested page size.
@@ -175,7 +178,7 @@ Proper usage of cursor pagination should have an ordering field that satisfies t
175178
* Should be a non-nullable value that can be coerced to a string.
176179
* The field should have a database index.
177180

178-
Using an ordering field that does not satisfy these constraints will generally still work, but you'll be loosing some of the benefits of cursor pagination.
181+
Using an ordering field that does not satisfy these constraints will generally still work, but you'll be losing some of the benefits of cursor pagination.
179182

180183
For more technical details on the implementation we use for cursor pagination, the ["Building cursors for the Disqus API"][disqus-cursor-api] blog post gives a good overview of the basic approach.
181184

docs/api-guide/parsers.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ using the `APIView` class based views.
5151
return Response({'received data': request.data})
5252

5353
Or, if you're using the `@api_view` decorator with function based views.
54+
55+
from rest_framework.decorators import api_view
56+
from rest_framework.decorators import parser_classes
5457

5558
@api_view(['POST'])
5659
@parser_classes((JSONParser,))

docs/api-guide/permissions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ Or, if you're using the `@api_view` decorator with function based views.
100100
}
101101
return Response(content)
102102

103+
__Note:__ when you set new permission classes through class attribute or decorators you're telling the view to ignore the default list set over the __settings.py__ file.
104+
103105
---
104106

105107
# API Reference

docs/api-guide/relations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ In cases where the cutoff is being enforced you may want to instead use a plain
459459

460460
assigned_to = serializers.SlugRelatedField(
461461
queryset=User.objects.all(),
462-
slug field='username',
462+
slug_field='username',
463463
style={'base_template': 'input.html'}
464464
)
465465

docs/api-guide/renderers.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ This renderer is suitable for CRUD-style web APIs that should also present a use
187187

188188
Note that views that have nested or list serializers for their input won't work well with the `AdminRenderer`, as the HTML forms are unable to properly support them.
189189

190+
**Note**: The `AdminRenderer` is only able to include links to detail pages when a properly configured `URL_FIELD_NAME` (`url` by default) attribute is present in the data. For `HyperlinkedModelSerializer` this will be the case, but for `ModelSerializer` or plain `Serializer` classes you'll need to make sure to include the field explicitly. For example here we use models `get_absolute_url` method:
191+
192+
class AccountSerializer(serializers.ModelSerializer):
193+
url = serializers.CharField(source='get_absolute_url', read_only=True)
194+
195+
class Meta:
196+
model = Account
197+
198+
190199
**.media_type**: `text/html`
191200

192201
**.format**: `'.admin'`

docs/api-guide/serializers.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,8 @@ To support multiple updates you'll need to do so explicitly. When writing your m
774774
* How should insertions be handled? Are they invalid, or do they create new objects?
775775
* How should removals be handled? Do they imply object deletion, or removing a relationship? Should they be silently ignored, or are they invalid?
776776
* How should ordering be handled? Does changing the position of two items imply any state change or is it ignored?
777+
778+
You will need to add an explicit `id` field to the instance serializer. The default implicitly-generated `id` field is marked as `read_only`. This causes it to be removed on updates. Once you declare it explicitly, it will be available in the list serializer's `update` method.
777779

778780
Here's an example of how you might choose to implement multiple updates:
779781

@@ -800,7 +802,13 @@ Here's an example of how you might choose to implement multiple updates:
800802
return ret
801803

802804
class BookSerializer(serializers.Serializer):
805+
# We need to identify elements in the list using their primary key,
806+
# so use a writable field here, rather than the default which would be read-only.
807+
id = serializers.IntegerField()
808+
803809
...
810+
id = serializers.IntegerField(required=False)
811+
804812
class Meta:
805813
list_serializer_class = BookListSerializer
806814

docs/api-guide/status-codes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ The 4xx class of status code is intended for cases in which the client seems to
8989
HTTP_428_PRECONDITION_REQUIRED
9090
HTTP_429_TOO_MANY_REQUESTS
9191
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
92+
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
9293

9394
## Server Error - 5xx
9495

docs/api-guide/versioning.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ Your URL conf must include a pattern that matches the version with a `'version'`
130130

131131
urlpatterns = [
132132
url(
133-
r'^(?P<version>[v1|v2]+)/bookings/$',
133+
r'^(?P<version>(v1|v2))/bookings/$',
134134
bookings_list,
135135
name='bookings-list'
136136
),
137137
url(
138-
r'^(?P<version>[v1|v2]+)/bookings/(?P<pk>[0-9]+)/$',
138+
r'^(?P<version>(v1|v2))/bookings/(?P<pk>[0-9]+)/$',
139139
bookings_detail,
140140
name='bookings-detail'
141141
)

docs/img/drfdocs.png

298 KB
Loading

docs/img/rest-framework-docs.png

-74.8 KB
Binary file not shown.

docs/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ If you're intending to use the browsable API you'll probably also want to add RE
8686
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
8787
]
8888

89-
Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace.
89+
Note that the URL path can be whatever you want, but you must include `'rest_framework.urls'` with the `'rest_framework'` namespace. You may leave out the namespace in Django 1.9+, and REST framework will set it for you.
9090

9191
## Example
9292

@@ -231,7 +231,7 @@ Send a description of the issue via email to [rest-framework-security@googlegrou
231231

232232
## License
233233

234-
Copyright (c) 2011-2015, Tom Christie
234+
Copyright (c) 2011-2016, Tom Christie
235235
All rights reserved.
236236

237237
Redistribution and use in source and binary forms, with or without
@@ -258,6 +258,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
258258
[eventbrite]: https://www.eventbrite.co.uk/about/
259259
[markdown]: http://pypi.python.org/pypi/Markdown/
260260
[django-filter]: http://pypi.python.org/pypi/django-filter
261+
[django-crispy-forms]: https://github.com/maraujop/django-crispy-forms
261262
[django-guardian]: https://github.com/lukaszb/django-guardian
262263
[0.4]: https://github.com/tomchristie/django-rest-framework/tree/0.4.X
263264
[image]: img/quickstart.png

docs/topics/browsable-api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ By default, the API will return the format specified by the headers, which in th
1717

1818
## Customizing
1919

20-
The browsable API is built with [Twitter's Bootstrap][bootstrap] (v 2.1.1), making it easy to customize the look-and-feel.
20+
The browsable API is built with [Twitter's Bootstrap][bootstrap] (v 3.3.5), making it easy to customize the look-and-feel.
2121

2222
To customize the default style, create a template called `rest_framework/api.html` that extends from `rest_framework/base.html`. For example:
2323

docs/topics/documenting-your-api.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,29 @@ The most common way to document Web APIs today is to produce documentation that
1212

1313
---
1414

15-
#### Django REST Swagger
15+
#### DRF Docs
1616

17-
Marc Gibbons' [Django REST Swagger][django-rest-swagger] integrates REST framework with the [Swagger][swagger] API documentation tool. The package produces well presented API documentation, and includes interactive tools for testing API endpoints.
17+
[DRF Docs][drfdocs-repo] allows you to document Web APIs made with Django REST Framework and it is authored by Emmanouil Konstantinidis. It's made to work out of the box and its setup should not take more than a couple of minutes. Complete documentation can be found on the [website][drfdocs-website] while there is also a [demo][drfdocs-demo] available for people to see what it looks like.
1818

19-
The package is fully documented, well supported, and comes highly recommended.
19+
Features include customizing the template with your branding, settings for hiding the docs depending on the environment and more.
2020

21-
Django REST Swagger supports REST framework versions 2.3 and above.
21+
Both this package and Django REST Swagger are fully documented, well supported, and come highly recommended.
2222

23-
![Screenshot - Django REST Swagger][image-django-rest-swagger]
23+
![Screenshot - DRF docs][image-drf-docs]
2424

2525
---
2626

27-
#### REST Framework Docs
27+
#### Django REST Swagger
2828

29-
The [REST Framework Docs][rest-framework-docs] package is an earlier project, also by Marc Gibbons, that offers clean, simple autogenerated documentation for your API.
29+
Marc Gibbons' [Django REST Swagger][django-rest-swagger] integrates REST framework with the [Swagger][swagger] API documentation tool. The package produces well presented API documentation, and includes interactive tools for testing API endpoints.
3030

31-
![Screenshot - REST Framework Docs][image-rest-framework-docs]
31+
Django REST Swagger supports REST framework versions 2.3 and above.
32+
33+
Mark is also the author of the [REST Framework Docs][rest-framework-docs] package which offers clean, simple autogenerated documentation for your API but is deprecated and has moved to Django REST Swagger.
34+
35+
Both this package and DRF docs are fully documented, well supported, and come highly recommended.
36+
37+
![Screenshot - Django REST Swagger][image-django-rest-swagger]
3238

3339
---
3440

@@ -100,13 +106,16 @@ In this approach, rather than documenting the available API endpoints up front,
100106
To implement a hypermedia API you'll need to decide on an appropriate media type for the API, and implement a custom renderer and parser for that media type. The [REST, Hypermedia & HATEOAS][hypermedia-docs] section of the documentation includes pointers to background reading, as well as links to various hypermedia formats.
101107

102108
[cite]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
109+
[drfdocs-repo]: https://github.com/ekonstantinidis/django-rest-framework-docs
110+
[drfdocs-website]: http://www.drfdocs.com/
111+
[drfdocs-demo]: http://demo.drfdocs.com/
103112
[django-rest-swagger]: https://github.com/marcgibbons/django-rest-swagger
104113
[swagger]: https://developers.helloreverb.com/swagger/
105114
[rest-framework-docs]: https://github.com/marcgibbons/django-rest-framework-docs
106115
[apiary]: http://apiary.io/
107116
[markdown]: http://daringfireball.net/projects/markdown/
108117
[hypermedia-docs]: rest-hypermedia-hateoas.md
118+
[image-drf-docs]: ../img/drfdocs.png
109119
[image-django-rest-swagger]: ../img/django-rest-swagger.png
110-
[image-rest-framework-docs]: ../img/rest-framework-docs.png
111120
[image-apiary]: ../img/apiary.png
112121
[image-self-describing-api]: ../img/self-describing.png

0 commit comments

Comments
 (0)