django-rest-framework/docs/tutorial/quickstart.md

204 lines
6.9 KiB
Markdown
Raw Normal View History

2012-10-09 15:01:17 +04:00
# Quickstart
We're going to create a simple API to allow admin users to view and edit the users and groups in the system.
## Project setup
Create a new Django project named `tutorial`, then start a new app called `quickstart`.
2014-08-18 14:55:22 +04:00
# Create the project directory
mkdir tutorial
cd tutorial
2013-05-28 18:09:23 +04:00
# Create a virtualenv to isolate our package dependencies locally
virtualenv env
source env/bin/activate # On Windows use `env\Scripts\activate`
# Install Django and Django REST framework into the virtualenv
pip install django
pip install djangorestframework
2014-08-20 19:24:52 +04:00
# Set up a new project with a single application
2014-12-05 12:44:01 +03:00
django-admin.py startproject tutorial .
2014-08-20 19:24:52 +04:00
cd tutorial
django-admin.py startapp quickstart
2014-12-08 19:38:17 +03:00
cd ..
2014-08-20 19:24:52 +04:00
Now sync your database for the first time:
python manage.py migrate
We'll also create an initial user named `admin` with a password of `password`. We'll authenticate as that user later in our example.
2014-08-20 19:24:52 +04:00
python manage.py createsuperuser
Once you've set up a database and initial user created and ready to go, open up the app's directory and we'll get coding...
2012-10-09 15:01:17 +04:00
## Serializers
2014-08-20 19:24:52 +04:00
First up we're going to define some serializers. Let's create a new module named `tutorial/quickstart/serializers.py` that we'll use for our data representations.
2012-10-09 15:01:17 +04:00
2013-05-02 15:08:05 +04:00
from django.contrib.auth.models import User, Group
2012-10-09 15:01:17 +04:00
from rest_framework import serializers
2014-08-16 06:45:28 +04:00
2012-10-09 15:01:17 +04:00
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
2014-08-16 06:45:28 +04:00
2012-10-09 15:01:17 +04:00
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
2013-05-02 15:08:05 +04:00
fields = ('url', 'name')
2012-10-09 15:01:17 +04:00
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.
## Views
2014-08-20 19:24:52 +04:00
Right, we'd better write some views then. Open `tutorial/quickstart/views.py` and get typing.
2012-10-09 15:01:17 +04:00
from django.contrib.auth.models import User, Group
2013-05-02 15:08:05 +04:00
from rest_framework import viewsets
2014-08-20 19:24:52 +04:00
from tutorial.quickstart.serializers import UserSerializer, GroupSerializer
2014-08-16 06:45:28 +04:00
2013-05-02 15:08:05 +04:00
class UserViewSet(viewsets.ModelViewSet):
2012-10-09 15:01:17 +04:00
"""
2013-05-02 15:08:05 +04:00
API endpoint that allows users to be viewed or edited.
2012-10-09 15:01:17 +04:00
"""
2013-05-02 15:08:05 +04:00
queryset = User.objects.all()
2012-10-09 15:01:17 +04:00
serializer_class = UserSerializer
2014-08-16 06:45:28 +04:00
2013-05-02 15:08:05 +04:00
class GroupViewSet(viewsets.ModelViewSet):
2012-10-09 15:01:17 +04:00
"""
2013-05-02 15:08:05 +04:00
API endpoint that allows groups to be viewed or edited.
2012-10-09 15:01:17 +04:00
"""
2013-05-02 15:08:05 +04:00
queryset = Group.objects.all()
2012-10-09 15:01:17 +04:00
serializer_class = GroupSerializer
Rather than write multiple views we're grouping together all the common behavior into classes called `ViewSets`.
2013-05-02 15:08:05 +04:00
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.
2012-10-09 15:01:17 +04:00
Notice that our viewset classes here are a little different from those in the [frontpage example][readme-example-api], as they include `queryset` and `serializer_class` attributes, instead of a `model` attribute.
For trivial cases you can simply set a `model` attribute on the `ViewSet` class and the serializer and queryset will be automatically generated for you. Setting the `queryset` and/or `serializer_class` attributes gives you more explicit control of the API behaviour, and is the recommended style for most applications.
2012-10-09 15:01:17 +04:00
## URLs
Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
2012-10-09 15:01:17 +04:00
2014-08-20 19:24:52 +04:00
from django.conf.urls import url, include
2013-05-02 15:08:05 +04:00
from rest_framework import routers
2014-08-20 19:24:52 +04:00
from tutorial.quickstart import views
2012-10-09 15:01:17 +04:00
2013-05-02 15:08:05 +04:00
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
2012-10-09 15:01:17 +04:00
2013-05-02 15:08:05 +04:00
# Wire up our API using automatic URL routing.
2014-11-29 22:23:55 +03:00
# Additionally, we include login URLs for the browsable API.
2014-08-20 19:24:52 +04:00
urlpatterns = [
2013-05-02 15:08:05 +04:00
url(r'^', include(router.urls)),
2012-10-09 15:01:17 +04:00
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
2014-08-20 19:24:52 +04:00
]
2012-10-09 15:01:17 +04:00
2013-05-02 15:08:05 +04:00
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.
2012-10-09 15:01:17 +04:00
2013-05-02 15:08:05 +04:00
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.
2012-10-09 15:01:17 +04:00
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.
2012-10-09 15:01:17 +04:00
## Settings
We'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in `tutorial/settings.py`
2012-10-09 15:01:17 +04:00
INSTALLED_APPS = (
...
'rest_framework',
)
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
2012-10-09 15:01:17 +04:00
'PAGINATE_BY': 10
}
2012-12-05 15:20:03 +04:00
Okay, we're done.
---
## Testing our API
We're now ready to test the API we've built. Let's fire up the server from the command line.
python ./manage.py runserver
We can now access our API, both from the command-line, using tools like `curl`...
2014-08-16 06:45:28 +04:00
bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
{
2014-08-16 06:45:28 +04:00
"count": 2,
"next": null,
"previous": null,
"results": [
{
2014-08-16 06:45:28 +04:00
"email": "admin@example.com",
"groups": [],
"url": "http://127.0.0.1:8000/users/1/",
"username": "admin"
2014-08-16 06:45:28 +04:00
},
{
2014-08-16 06:45:28 +04:00
"email": "tom@example.com",
"groups": [ ],
"url": "http://127.0.0.1:8000/users/2/",
"username": "tom"
}
]
}
2014-12-04 14:20:33 +03:00
Or using the [httpie][httpie], command line tool...
bash: http -a username:password http://127.0.0.1:8000/users/
2014-12-01 16:39:53 +03:00
2014-12-04 14:20:33 +03:00
HTTP/1.1 200 OK
...
2014-12-01 16:39:53 +03:00
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"email": "admin@example.com",
"groups": [],
"url": "http://localhost:8000/users/1/",
"username": "paul"
},
{
"email": "tom@example.com",
"groups": [ ],
"url": "http://127.0.0.1:8000/users/2/",
"username": "tom"
}
]
}
Or directly through the browser...
![Quick start image][image]
2014-08-20 19:24:52 +04:00
If you're working through the browser, make sure to login using the control in the top right corner.
Great, that was easy!
If you want to get a more in depth understanding of how REST framework fits together head on over to [the tutorial][tutorial], or start browsing the [API guide][guide].
[readme-example-api]: ../#example
2012-10-09 17:12:38 +04:00
[image]: ../img/quickstart.png
[tutorial]: 1-serialization.md
[guide]: ../#api-guide
2014-12-01 16:39:53 +03:00
[httpie]: https://github.com/jakubroztocil/httpie#installation