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.
2013-05-20 16:43:26 +04:00
## 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
2013-05-20 16:43:26 +04:00
cd tutorial
2013-05-28 18:09:23 +04:00
# Create a virtualenv to isolate our package dependencies locally
2013-05-20 16:43:26 +04:00
virtualenv env
2013-09-02 12:17:51 +04:00
source env/bin/activate # On Windows use `env\Scripts\activate`
2013-05-20 16:43:26 +04:00
# 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-17 18:22:27 +03:00
django-admin.py startproject tutorial . # Note the trailing '.' character
2014-08-20 19:24:52 +04:00
cd tutorial
django-admin.py startapp quickstart
2014-12-08 19:38:17 +03:00
cd ..
2013-05-20 16:43:26 +04:00
2014-08-20 19:24:52 +04:00
Now sync your database for the first time:
2013-05-20 16:43:26 +04:00
2014-10-09 18:11:19 +04:00
python manage.py migrate
2013-05-20 16:43:26 +04:00
2016-02-04 09:26:15 +03:00
We'll also create an initial user named `admin` with a password of `password123` . We'll authenticate as that user later in our example.
2014-08-20 19:24:52 +04:00
2014-10-09 18:11:19 +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
"""
2015-07-30 16:18:09 +03:00
queryset = User.objects.all().order_by('-date_joined')
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
2013-09-23 08:03:09 +04:00
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
## URLs
2013-05-30 14:11:42 +04:00
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
2016-07-08 10:38:50 +03: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
2013-05-02 08:26:40 +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
2013-05-20 16:43:26 +04:00
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 = {
2012-10-18 02:09:11 +04:00
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),
2015-03-04 18:51:00 +03:00
'PAGE_SIZE': 10
2012-10-09 15:01:17 +04:00
}
2012-12-05 15:20:03 +04:00
Okay, we're done.
2012-10-09 16:50:26 +04:00
---
## Testing our API
2013-05-20 16:43:26 +04:00
We're now ready to test the API we've built. Let's fire up the server from the command line.
2016-06-06 14:03:37 +03:00
python manage.py runserver
2013-05-20 16:43:26 +04:00
2012-10-09 16:50:26 +04:00
We can now access our API, both from the command-line, using tools like `curl` ...
2016-02-04 09:26:15 +03:00
bash: curl -H 'Accept: application/json; indent=4' -u admin:password123 http://127.0.0.1:8000/users/
2012-10-09 16:50:26 +04:00
{
2014-08-16 06:45:28 +04:00
"count": 2,
"next": null,
"previous": null,
2012-10-09 16:50:26 +04:00
"results": [
{
2014-08-16 06:45:28 +04:00
"email": "admin@example.com",
"groups": [],
"url": "http://127.0.0.1:8000/users/1/",
2012-10-09 16:50:26 +04:00
"username": "admin"
2014-08-16 06:45:28 +04:00
},
2012-10-09 16:50:26 +04:00
{
2014-08-16 06:45:28 +04:00
"email": "tom@example.com",
"groups": [ ],
"url": "http://127.0.0.1:8000/users/2/",
2012-10-09 16:50:26 +04:00
"username": "tom"
}
]
}
2014-12-04 14:20:33 +03:00
Or using the [httpie][httpie], command line tool...
2016-02-17 10:08:45 +03:00
bash: http -a admin:password123 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"
}
]
}
2016-06-06 14:03:37 +03:00
Or directly through the browser, by going to the URL `http://127.0.0.1:8000/users/` ...
2012-10-09 16:50:26 +04:00
![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.
2012-10-09 16:50:26 +04:00
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].
2013-12-13 19:30:59 +04:00
[readme-example-api]: ../#example
2012-10-09 17:12:38 +04:00
[image]: ../img/quickstart.png
2012-10-09 16:50:26 +04:00
[tutorial]: 1-serialization.md
2012-10-18 02:09:11 +04:00
[guide]: ../#api-guide
2014-12-01 16:39:53 +03:00
[httpie]: https://github.com/jakubroztocil/httpie#installation