aboutsummaryrefslogtreecommitdiffstats
path: root/docs/tutorial/quickstart.md
diff options
context:
space:
mode:
authorTom Christie2013-05-09 00:57:27 -0700
committerTom Christie2013-05-09 00:57:27 -0700
commit9428d6ddb5ebc2d5d9c8557a52be09f0def69cca (patch)
tree41003692e65e08934fed7c0cee263e34da1a4110 /docs/tutorial/quickstart.md
parent0080bf8a00bcfb1988a5e73fae5635bf4969d534 (diff)
parent14482a966168a98d43099d00c163d1c8c3b6471b (diff)
downloaddjango-rest-framework-9428d6ddb5ebc2d5d9c8557a52be09f0def69cca.tar.bz2
Merge pull request #817 from maspwr/writable-nested-modelserializer
Merge master into writable-nested-modelserializer
Diffstat (limited to 'docs/tutorial/quickstart.md')
-rw-r--r--docs/tutorial/quickstart.md95
1 files changed, 25 insertions, 70 deletions
diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md
index 74084541..52fe3acf 100644
--- a/docs/tutorial/quickstart.md
+++ b/docs/tutorial/quickstart.md
@@ -8,7 +8,7 @@ Create a new Django project, and start a new app called `quickstart`. Once you'
First up we're going to define some serializers in `quickstart/serializers.py` that we'll use for our data representations.
- from django.contrib.auth.models import User, Group, Permission
+ from django.contrib.auth.models import User, Group
from rest_framework import serializers
@@ -19,109 +19,64 @@ First up we're going to define some serializers in `quickstart/serializers.py` t
class GroupSerializer(serializers.HyperlinkedModelSerializer):
- permissions = serializers.ManySlugRelatedField(
- slug_field='codename',
- queryset=Permission.objects.all()
- )
-
class Meta:
model = Group
- fields = ('url', 'name', 'permissions')
+ fields = ('url', 'name')
Notice that we're using hyperlinked relations in this case, with `HyperlinkedModelSerializer`. You can also use primary key and various other relationships, but hyperlinking is good RESTful design.
-We've also overridden the `permission` field on the `GroupSerializer`. In this case we don't want to use a hyperlinked representation, but instead use the list of permission codenames associated with the group, so we've used a `ManySlugRelatedField`, using the `codename` field for the representation.
-
## Views
Right, we'd better write some views then. Open `quickstart/views.py` and get typing.
from django.contrib.auth.models import User, Group
- from rest_framework import generics
- from rest_framework.decorators import api_view
- from rest_framework.reverse import reverse
- from rest_framework.response import Response
+ from rest_framework import viewsets
from quickstart.serializers import UserSerializer, GroupSerializer
- @api_view(['GET'])
- def api_root(request, format=None):
- """
- The entry endpoint of our API.
- """
- return Response({
- 'users': reverse('user-list', request=request),
- 'groups': reverse('group-list', request=request),
- })
-
-
- class UserList(generics.ListCreateAPIView):
- """
- API endpoint that represents a list of users.
- """
- model = User
- serializer_class = UserSerializer
-
-
- class UserDetail(generics.RetrieveUpdateDestroyAPIView):
+ class UserViewSet(viewsets.ModelViewSet):
"""
- API endpoint that represents a single user.
+ API endpoint that allows users to be viewed or edited.
"""
- model = User
+ queryset = User.objects.all()
serializer_class = UserSerializer
- class GroupList(generics.ListCreateAPIView):
+ class GroupViewSet(viewsets.ModelViewSet):
"""
- API endpoint that represents a list of groups.
+ API endpoint that allows groups to be viewed or edited.
"""
- model = Group
- serializer_class = GroupSerializer
-
-
- class GroupDetail(generics.RetrieveUpdateDestroyAPIView):
- """
- API endpoint that represents a single group.
- """
- model = Group
+ queryset = Group.objects.all()
serializer_class = GroupSerializer
-Let's take a moment to look at what we've done here before we move on. We have one function-based view representing the root of the API, and four class-based views which map to our database models, and specify which serializers should be used for representing that data. Pretty simple stuff.
+Rather that write multiple views we're grouping together all the common behavior into classes called `ViewSets`.
+
+We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.
## URLs
-Okay, let's wire this baby up. On to `quickstart/urls.py`...
+Okay, now let's wire up the API URLs. On to `quickstart/urls.py`...
from django.conf.urls import patterns, url, include
- from rest_framework.urlpatterns import format_suffix_patterns
- from quickstart.views import UserList, UserDetail, GroupList, GroupDetail
-
-
- urlpatterns = patterns('quickstart.views',
- url(r'^$', 'api_root'),
- url(r'^users/$', UserList.as_view(), name='user-list'),
- url(r'^users/(?P<pk>\d+)/$', UserDetail.as_view(), name='user-detail'),
- url(r'^groups/$', GroupList.as_view(), name='group-list'),
- url(r'^groups/(?P<pk>\d+)/$', GroupDetail.as_view(), name='group-detail'),
- )
-
-
- # Format suffixes
- urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'api'])
+ from rest_framework import routers
+ from quickstart import views
+ router = routers.DefaultRouter()
+ router.register(r'users', views.UserViewSet)
+ router.register(r'groups', views.GroupViewSet)
- # Default login/logout views
- urlpatterns += patterns('',
+ # Wire up our API using automatic URL routing.
+ # Additionally, we include login URLs for the browseable API.
+ urlpatterns = patterns('',
+ url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)
-There's a few things worth noting here.
-
-Firstly the names `user-detail` and `group-detail` are important. We're using the default hyperlinked relationships without explicitly specifying the view names, so we need to use names of the style `{modelname}-detail` to represent the model instance views.
+Because we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.
-Secondly, we're modifying the urlpatterns using `format_suffix_patterns`, to append optional `.json` style suffixes to our URLs.
+Again, if we need more control over the API URLs we can simply drop down to using regular class based views, and writing the URL conf explicitly.
-Finally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browseable API.
+Finally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browsable API.
## Settings