Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
08c7853
Start test case
lovelydinosaur Aug 1, 2016
5abac93
Merge branch 'master' into requests-client
lovelydinosaur Aug 12, 2016
3d1fff3
Added 'requests' test client
lovelydinosaur Aug 15, 2016
e76ca6e
Address typos
lovelydinosaur Aug 15, 2016
6ede654
Graceful fallback if requests is not installed.
lovelydinosaur Aug 17, 2016
049a39e
Add cookie support
lovelydinosaur Aug 17, 2016
64e19c7
Tests for auth and CSRF
lovelydinosaur Aug 17, 2016
da47c34
Py3 compat
lovelydinosaur Aug 17, 2016
5311769
py3 compat
lovelydinosaur Aug 17, 2016
0b3db02
py3 compat
lovelydinosaur Aug 17, 2016
0cc3f50
Add get_requests_client
lovelydinosaur Aug 18, 2016
e4f6928
Added SchemaGenerator.should_include_link
lovelydinosaur Sep 2, 2016
46b9e4e
add settings for html cutoff on related fields
Aug 22, 2016
a556b9c
Router doesn't work if prefix is blank, though project urls.py handle…
c17r Sep 14, 2016
8609c9c
Fix Django 1.10 to-many deprecation
Sep 15, 2016
197b63a
Add django.core.urlresolvers compatibility
Sep 15, 2016
bb37cb7
Update django-filter & django-guardian
Sep 15, 2016
a372a8e
Check for empty router prefix; adjust URL accordingly
c17r Sep 15, 2016
a084924
Fix misc django deprecations
Sep 15, 2016
3bfb0b7
Use TOC extension instead of header
Sep 15, 2016
3bdb0e9
Fix deprecations for py3k
Sep 16, 2016
a0a8b98
Add py3k compatibility to is_simple_callable
Sep 22, 2016
adcf653
Add is_simple_callable tests
Sep 22, 2016
b3afcb2
Drop python 3.2 support (EOL, Dropped by Django)
Sep 22, 2016
b516712
schema_renderers= should *set* the renderers, not append to them.
lovelydinosaur Sep 28, 2016
37b3475
API client (#4424)
lovelydinosaur Sep 29, 2016
c2cec78
Merge master
lovelydinosaur Sep 29, 2016
a60ef8c
Merge branch 'schema-renderers-only-for-root-view' into version-3-5
lovelydinosaur Sep 29, 2016
61b1189
Fix release notes
lovelydinosaur Sep 29, 2016
bc9b522
Merge branch 'rpkilby-fix-simple-callable' into version-3-5
lovelydinosaur Sep 29, 2016
9a4ed1b
Merge branch 'should_include_link' into version-3-5
lovelydinosaur Sep 29, 2016
24bf382
Merge branch 'html_cutoff_settings' of https://github.com/MobileWorks…
lovelydinosaur Sep 29, 2016
f455c67
Merge branch 'MobileWorks-html_cutoff_settings' into version-3-5
lovelydinosaur Sep 29, 2016
b689a3b
Add note about 'User account is disabled.' vs 'Unable to log in'
lovelydinosaur Sep 29, 2016
818ab45
Merge branch 'fix-deprecations' of https://github.com/rpkilby/django-…
lovelydinosaur Sep 29, 2016
ee2b165
Merge branch 'rpkilby-fix-deprecations' into version-3-5
lovelydinosaur Sep 29, 2016
c427144
Merge branch 'router-empty-prefix' of https://github.com/c17r/django-…
lovelydinosaur Sep 29, 2016
49ce3d6
Merge branch 'c17r-router-empty-prefix' into version-3-5
lovelydinosaur Sep 29, 2016
c3a9538
Clean up schema generation (#4527)
lovelydinosaur Sep 30, 2016
4ad5256
Handle multiple methods on custom action (#4529)
lovelydinosaur Sep 30, 2016
8044d38
RequestsClient, CoreAPIClient
lovelydinosaur Oct 4, 2016
a8501f7
exclude_from_schema
lovelydinosaur Oct 5, 2016
cd826ce
Added 'get_schema_view()' shortcut
lovelydinosaur Oct 5, 2016
7e3a3a4
Added schema descriptions
lovelydinosaur Oct 5, 2016
1084dca
Better descriptions for schemas
lovelydinosaur Oct 5, 2016
7edee80
Add type annotation to schema generation
lovelydinosaur Oct 6, 2016
b44ab76
Coerce schema 'pk' in path to actual field name
lovelydinosaur Oct 6, 2016
0724420
Deprecations move into assertion errors
lovelydinosaur Oct 6, 2016
3eb7fe6
Use get_schema_view in tests
lovelydinosaur Oct 7, 2016
5858168
Updte CoreJSON media type
lovelydinosaur Oct 7, 2016
69b4acd
Handle schema structure correctly when path prefixs exist. Closes #4401
lovelydinosaur Oct 7, 2016
fcf932f
Add PendingDeprecation to Router schema generation.
lovelydinosaur Oct 7, 2016
18aebbb
Added SCHEMA_COERCE_PATH_PK and SCHEMA_COERCE_METHOD_NAMES
lovelydinosaur Oct 10, 2016
3f3213b
Renamed and documented 'get_schema_fields' interface.
lovelydinosaur Oct 10, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Added SCHEMA_COERCE_PATH_PK and SCHEMA_COERCE_METHOD_NAMES
  • Loading branch information
lovelydinosaur committed Oct 10, 2016
commit 18aebbbe01a86d7d6d7638364a428c67f8374fd8
22 changes: 22 additions & 0 deletions docs/api-guide/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,28 @@ Default:

---

## Schema generation controls

#### SCHEMA_COERCE_PATH_PK

If set, this maps the `'pk'` identifier in the URL conf onto the actual field
name when generating a schema path parameter. Typically this will be `'id'`.
This gives a more suitable representation as "primary key" is an implementation
detail, wheras "identifier" is a more general concept.

Default: `True`

#### SCHEMA_COERCE_METHOD_NAMES

If set, this is used to map internal viewset method names onto external action
names used in the schema generation. This allows us to generate names that
are more suitable for an external representation than those that are used
internally in the codebase.

Default: `{'retrieve': 'read', 'destroy': 'delete'}`

---

## Content type controls

#### URL_FORMAT_OVERRIDE
Expand Down
14 changes: 7 additions & 7 deletions docs/tutorial/1-serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ The first thing we need to get started on our Web API is to provide a way of ser


class SnippetSerializer(serializers.Serializer):
pk = serializers.IntegerField(read_only=True)
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(required=False, allow_blank=True, max_length=100)
code = serializers.CharField(style={'base_template': 'textarea.html'})
linenos = serializers.BooleanField(required=False)
Expand Down Expand Up @@ -144,13 +144,13 @@ We've now got a few snippet instances to play with. Let's take a look at serial

serializer = SnippetSerializer(snippet)
serializer.data
# {'pk': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}
# {'id': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}

At this point we've translated the model instance into Python native datatypes. To finalize the serialization process we render the data into `json`.

content = JSONRenderer().render(serializer.data)
content
# '{"pk": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'
# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'

Deserialization is similar. First we parse a stream into Python native datatypes...

Expand All @@ -175,7 +175,7 @@ We can also serialize querysets instead of model instances. To do so we simply

serializer = SnippetSerializer(Snippet.objects.all(), many=True)
serializer.data
# [OrderedDict([('pk', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('pk', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
# [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]

## Using ModelSerializers

Expand Down Expand Up @@ -259,12 +259,12 @@ Note that because we want to be able to POST to this view from clients that won'
We'll also need a view which corresponds to an individual snippet, and can be used to retrieve, update or delete the snippet.

@csrf_exempt
def snippet_detail(request, pk):
def snippet_detail(request, id):
"""
Retrieve, update or delete a code snippet.
"""
try:
snippet = Snippet.objects.get(pk=pk)
snippet = Snippet.objects.get(id=id)
except Snippet.DoesNotExist:
return HttpResponse(status=404)

Expand All @@ -291,7 +291,7 @@ Finally we need to wire these views up. Create the `snippets/urls.py` file:

urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),
url(r'^snippets/(?P<id>[0-9]+)/$', views.snippet_detail),
]

We also need to wire up the root urlconf, in the `tutorial/urls.py` file, to include our snippet app's URLs.
Expand Down
8 changes: 4 additions & 4 deletions docs/tutorial/2-requests-and-responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ Our instance view is an improvement over the previous example. It's a little mo
Here is the view for an individual snippet, in the `views.py` module.

@api_view(['GET', 'PUT', 'DELETE'])
def snippet_detail(request, pk):
def snippet_detail(request, id):
"""
Retrieve, update or delete a snippet instance.
"""
try:
snippet = Snippet.objects.get(pk=pk)
snippet = Snippet.objects.get(id=id)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)

Expand Down Expand Up @@ -104,7 +104,7 @@ Start by adding a `format` keyword argument to both of the views, like so.

and

def snippet_detail(request, pk, format=None):
def snippet_detail(request, id, format=None):

Now update the `urls.py` file slightly, to append a set of `format_suffix_patterns` in addition to the existing URLs.

Expand All @@ -114,7 +114,7 @@ Now update the `urls.py` file slightly, to append a set of `format_suffix_patter

urlpatterns = [
url(r'^snippets/$', views.snippet_list),
url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail),
url(r'^snippets/(?P<id>[0-9]+)$', views.snippet_detail),
]

urlpatterns = format_suffix_patterns(urlpatterns)
Expand Down
18 changes: 9 additions & 9 deletions docs/tutorial/3-class-based-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ So far, so good. It looks pretty similar to the previous case, but we've got be
"""
Retrieve, update or delete a snippet instance.
"""
def get_object(self, pk):
def get_object(self, id):
try:
return Snippet.objects.get(pk=pk)
return Snippet.objects.get(id=id)
except Snippet.DoesNotExist:
raise Http404

def get(self, request, pk, format=None):
snippet = self.get_object(pk)
def get(self, request, id, format=None):
snippet = self.get_object(id)
serializer = SnippetSerializer(snippet)
return Response(serializer.data)

def put(self, request, pk, format=None):
snippet = self.get_object(pk)
def put(self, request, id, format=None):
snippet = self.get_object(id)
serializer = SnippetSerializer(snippet, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def delete(self, request, pk, format=None):
snippet = self.get_object(pk)
def delete(self, request, id, format=None):
snippet = self.get_object(id)
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

Expand All @@ -70,7 +70,7 @@ We'll also need to refactor our `urls.py` slightly now we're using class-based v

urlpatterns = [
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
url(r'^snippets/(?P<id>[0-9]+)/$', views.SnippetDetail.as_view()),
]

urlpatterns = format_suffix_patterns(urlpatterns)
Expand Down
4 changes: 2 additions & 2 deletions docs/tutorial/4-authentication-and-permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Make sure to also import the `UserSerializer` class
Finally we need to add those views into the API, by referencing them from the URL conf. Add the following to the patterns in `urls.py`.

url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
url(r'^users/(?P<id>[0-9]+)/$', views.UserDetail.as_view()),

## Associating Snippets with Users

Expand Down Expand Up @@ -150,7 +150,7 @@ The `r'^api-auth/'` part of pattern can actually be whatever URL you want to use

Now if you open up the browser again and refresh the page you'll see a 'Login' link in the top right of the page. If you log in as one of the users you created earlier, you'll be able to create code snippets again.

Once you've created a few code snippets, navigate to the '/users/' endpoint, and notice that the representation includes a list of the snippet pks that are associated with each user, in each user's 'snippets' field.
Once you've created a few code snippets, navigate to the '/users/' endpoint, and notice that the representation includes a list of the snippet ids that are associated with each user, in each user's 'snippets' field.

## Object level permissions

Expand Down
14 changes: 7 additions & 7 deletions docs/tutorial/5-relationships-and-hyperlinked-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ We'll add a url pattern for our new API root in `snippets/urls.py`:

And then add a url pattern for the snippet highlights:

url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),
url(r'^snippets/(?P<id>[0-9]+)/highlight/$', views.SnippetHighlight.as_view()),

## Hyperlinking our API

Expand All @@ -67,7 +67,7 @@ In this case we'd like to use a hyperlinked style between entities. In order to

The `HyperlinkedModelSerializer` has the following differences from `ModelSerializer`:

* It does not include the `pk` field by default.
* It does not include the `id` field by default.
* It includes a `url` field, using `HyperlinkedIdentityField`.
* Relationships use `HyperlinkedRelatedField`,
instead of `PrimaryKeyRelatedField`.
Expand All @@ -80,7 +80,7 @@ We can easily re-write our existing serializers to use hyperlinking. In your `sn

class Meta:
model = Snippet
fields = ('url', 'pk', 'highlight', 'owner',
fields = ('url', 'id', 'highlight', 'owner',
'title', 'code', 'linenos', 'language', 'style')


Expand All @@ -89,7 +89,7 @@ We can easily re-write our existing serializers to use hyperlinking. In your `sn

class Meta:
model = User
fields = ('url', 'pk', 'username', 'snippets')
fields = ('url', 'id', 'username', 'snippets')

Notice that we've also added a new `'highlight'` field. This field is of the same type as the `url` field, except that it points to the `'snippet-highlight'` url pattern, instead of the `'snippet-detail'` url pattern.

Expand All @@ -116,16 +116,16 @@ After adding all those names into our URLconf, our final `snippets/urls.py` file
url(r'^snippets/$',
views.SnippetList.as_view(),
name='snippet-list'),
url(r'^snippets/(?P<pk>[0-9]+)/$',
url(r'^snippets/(?P<id>[0-9]+)/$',
views.SnippetDetail.as_view(),
name='snippet-detail'),
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$',
url(r'^snippets/(?P<id>[0-9]+)/highlight/$',
views.SnippetHighlight.as_view(),
name='snippet-highlight'),
url(r'^users/$',
views.UserList.as_view(),
name='user-list'),
url(r'^users/(?P<pk>[0-9]+)/$',
url(r'^users/(?P<id>[0-9]+)/$',
views.UserDetail.as_view(),
name='user-detail')
])
Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial/6-viewsets-and-routers.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ Now that we've bound our resources into concrete views, we can register the view
urlpatterns = format_suffix_patterns([
url(r'^$', api_root),
url(r'^snippets/$', snippet_list, name='snippet-list'),
url(r'^snippets/(?P<pk>[0-9]+)/$', snippet_detail, name='snippet-detail'),
url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
url(r'^snippets/(?P<id>[0-9]+)/$', snippet_detail, name='snippet-detail'),
url(r'^snippets/(?P<id>[0-9]+)/highlight/$', snippet_highlight, name='snippet-highlight'),
url(r'^users/$', user_list, name='user-list'),
url(r'^users/(?P<pk>[0-9]+)/$', user_detail, name='user-detail')
url(r'^users/(?P<id>[0-9]+)/$', user_detail, name='user-detail')
])

## Using Routers
Expand Down
26 changes: 13 additions & 13 deletions docs/tutorial/7-schemas-and-client-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ First we'll load the API schema using the command line client.
$ coreapi get http://127.0.0.1:8000/schema/
<Pastebin API "http://127.0.0.1:8000/schema/">
snippets: {
highlight(pk)
highlight(id)
list()
retrieve(pk)
read(id)
}
users: {
list()
retrieve(pk)
read(id)
}

We haven't authenticated yet, so right now we're only able to see the read only
Expand All @@ -119,7 +119,7 @@ Let's try listing the existing snippets, using the command line client:
[
{
"url": "http://127.0.0.1:8000/snippets/1/",
"pk": 1,
"id": 1,
"highlight": "http://127.0.0.1:8000/snippets/1/highlight/",
"owner": "lucy",
"title": "Example",
Expand All @@ -133,7 +133,7 @@ Let's try listing the existing snippets, using the command line client:
Some of the API endpoints require named parameters. For example, to get back
the highlight HTML for a particular snippet we need to provide an id.

$ coreapi action snippets highlight --param pk=1
$ coreapi action snippets highlight --param id=1
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>
Expand All @@ -160,16 +160,16 @@ set of available interactions.
Pastebin API "http://127.0.0.1:8000/schema/">
snippets: {
create(code, [title], [linenos], [language], [style])
destroy(pk)
highlight(pk)
delete(id)
highlight(id)
list()
partial_update(pk, [title], [code], [linenos], [language], [style])
retrieve(pk)
update(pk, code, [title], [linenos], [language], [style])
partial_update(id, [title], [code], [linenos], [language], [style])
read(id)
update(id, code, [title], [linenos], [language], [style])
}
users: {
list()
retrieve(pk)
read(id)
}

We're now able to interact with these endpoints. For example, to create a new
Expand All @@ -178,7 +178,7 @@ snippet:
$ coreapi action snippets create --param title="Example" --param code="print('hello, world')"
{
"url": "http://127.0.0.1:8000/snippets/7/",
"pk": 7,
"id": 7,
"highlight": "http://127.0.0.1:8000/snippets/7/highlight/",
"owner": "lucy",
"title": "Example",
Expand All @@ -190,7 +190,7 @@ snippet:

And to delete a snippet:

$ coreapi action snippets destroy --param pk=7
$ coreapi action snippets delete --param id=7

As well as the command line client, developers can also interact with your
API using client libraries. The Python client library is the first of these
Expand Down
Loading