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` .
# Set up a new project
django-admin.py startproject tutorial
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
# Create a new app
python manage.py startapp quickstart
Next you'll need to get a database set up and synced. If you just want to use SQLite for now, then you'll want to edit your `tutorial/settings.py` module to include something like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'database.sql',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': ''
}
}
The run `syncdb` like so:
2013-05-28 18:09:23 +04:00
python manage.py syncdb
2013-05-20 16:43:26 +04:00
Once you've set up a database and got everything synced and ready to go, open up the app's directory and we'll get coding...
2012-10-09 15:01:17 +04:00
## Serializers
First up we're going to define some serializers in `quickstart/serializers.py` that we'll use for our data representations.
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
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
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
2012-10-12 12:02:21 +04:00
Right, we'd better write some views then. Open `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
2012-10-09 15:01:17 +04:00
from quickstart.serializers import UserSerializer, GroupSerializer
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
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-05-02 15:08:05 +04:00
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.
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
from django.conf.urls import patterns, url, include
2013-05-02 15:08:05 +04:00
from rest_framework import routers
from 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.
# Additionally, we include login URLs for the browseable API.
urlpatterns = patterns('',
url(r'^', include(router.urls)),
2012-10-09 15:01:17 +04:00
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
)
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
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',),
2012-10-09 15:01:17 +04:00
'PAGINATE_BY': 10
}
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.
python ./manage.py runserver
2012-10-09 16:50:26 +04:00
We can now access our API, both from the command-line, using tools like `curl` ...
bash: curl -H 'Accept: application/json; indent=4' -u admin:password http://127.0.0.1:8000/users/
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"email": "admin@example.com",
"groups": [],
"url": "http://127.0.0.1:8000/users/1/",
"username": "admin"
},
{
"email": "tom@example.com",
2012-11-02 03:04:13 +04:00
"groups": [ ],
2012-10-09 16:50:26 +04:00
"url": "http://127.0.0.1:8000/users/2/",
"username": "tom"
}
]
}
Or directly through the browser...
![Quick start image][image]
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].
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