This commit is contained in:
Raphael Pierzina 2016-12-02 16:14:58 +00:00 committed by GitHub
commit 57daca419f

View File

@ -1,43 +1,76 @@
# Quickstart # Quickstart
We're going to create a simple API to allow admin users to view and edit the users and groups in the system. We're going to create a simple API to allow admin users to view and edit the
users and groups in the system.
## Requirements
* [Python][python]
* [pip][pip] - a tool for installing Python packages
* [virtualenv][virtualenv] - a tool to create isolated Python environments
## Project setup ## Project setup
Create a new Django project named `tutorial`, then start a new app called `quickstart`. ### Create a new Django project named `tutorial`, then start a new app called `quickstart`.
# Create the project directory Create the project directory
```text
mkdir tutorial mkdir tutorial
cd tutorial cd tutorial
```
# Create a virtualenv to isolate our package dependencies locally Create a virtualenv to isolate our package dependencies locally
```text
virtualenv env virtualenv env
source env/bin/activate # On Windows use `env\Scripts\activate` source env/bin/activate # On Linux or OS X
source env\Scripts\activate # On Windows
```
# Install Django and Django REST framework into the virtualenv Install Django and Django REST framework into the virtualenv
```text
pip install django pip install django
pip install djangorestframework pip install djangorestframework
```
# Set up a new project with a single application Set up a new project with a single application
```text
django-admin.py startproject tutorial . # Note the trailing '.' character django-admin.py startproject tutorial . # Note the trailing '.' character
cd tutorial cd tutorial
django-admin.py startapp quickstart django-admin.py startapp quickstart
cd .. cd ..
```
### Database
Now sync your database for the first time: Now sync your database for the first time:
```text
python manage.py migrate python manage.py migrate
```
We'll also create an initial user named `admin` with a password of `password123`. We'll authenticate as that user later in our example. We'll also create an initial user named `admin` with a password of
`password123`. We'll authenticate as that user later in our example.
```text
python manage.py createsuperuser 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... 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...
## Serializers ## Serializers
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. 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.
```python
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from rest_framework import serializers from rest_framework import serializers
@ -52,13 +85,18 @@ First up we're going to define some serializers. Let's create a new module named
class Meta: class Meta:
model = Group model = Group
fields = ('url', 'name') 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. 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 ## Views
Right, we'd better write some views then. Open `tutorial/quickstart/views.py` and get typing. Right, we'd better write some views then. Open `tutorial/quickstart/views.py`
and get typing.
```python
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from rest_framework import viewsets from rest_framework import viewsets
from tutorial.quickstart.serializers import UserSerializer, GroupSerializer from tutorial.quickstart.serializers import UserSerializer, GroupSerializer
@ -78,15 +116,19 @@ Right, we'd better write some views then. Open `tutorial/quickstart/views.py` a
""" """
queryset = Group.objects.all() queryset = Group.objects.all()
serializer_class = GroupSerializer serializer_class = GroupSerializer
```
Rather than write multiple views we're grouping together all the common behavior into classes called `ViewSets`. Rather than 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. 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 ## URLs
Okay, now let's wire up the API URLs. On to `tutorial/urls.py`... Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
```python
from django.conf.urls import url, include from django.conf.urls import url, include
from rest_framework import routers from rest_framework import routers
from tutorial.quickstart import views from tutorial.quickstart import views
@ -101,26 +143,37 @@ Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
url(r'^', include(router.urls)), url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
] ]
```
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. 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.
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. 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 browsable 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 ## 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` 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`
```python
INSTALLED_APPS = ( INSTALLED_APPS = (
... ...
'rest_framework', 'rest_framework',
) )
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',), 'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser', # Note the trailing ',' character, this needs to be a tuple
),
'PAGE_SIZE': 10 'PAGE_SIZE': 10
} }
```
Okay, we're done. Okay, we're done.
@ -128,13 +181,19 @@ Okay, we're done.
## Testing our API ## Testing our API
We're now ready to test the API we've built. Let's fire up the server from the command line. 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 python manage.py runserver
We can now access our API, both from the command-line, using tools like `curl`... 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:password123 http://127.0.0.1:8000/users/ ```bash
curl -H 'Accept: application/json; indent=4' -u admin:password123 http://127.0.0.1:8000/users/
```
```json
{ {
"count": 2, "count": 2,
"next": null, "next": null,
@ -154,13 +213,20 @@ We can now access our API, both from the command-line, using tools like `curl`..
} }
] ]
} }
```
Or using the [httpie][httpie], command line tool... Or using the [httpie][httpie], command line tool...
bash: http -a admin:password123 http://127.0.0.1:8000/users/ ```bash
http -a admin:password123 http://127.0.0.1:8000/users/
```
```text
HTTP/1.1 200 OK HTTP/1.1 200 OK
... ...
```
```json
{ {
"count": 2, "count": 2,
"next": null, "next": null,
@ -180,20 +246,27 @@ Or using the [httpie][httpie], command line tool...
} }
] ]
} }
```
Or directly through the browser, by going to the URL
Or directly through the browser, by going to the URL `http://127.0.0.1:8000/users/`... `http://127.0.0.1:8000/users/`...
![Quick start image][image] ![Quick start image][image]
If you're working through the browser, make sure to login using the control in the top right corner. If you're working through the browser, make sure to login using the control in
the top right corner.
Great, that was easy! 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]. 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 [readme-example-api]: ../#example
[image]: ../img/quickstart.png [image]: ../img/quickstart.png
[tutorial]: 1-serialization.md [tutorial]: 1-serialization.md
[guide]: ../#api-guide [guide]: ../#api-guide
[httpie]: https://github.com/jakubroztocil/httpie#installation [httpie]: https://github.com/jakubroztocil/httpie#installation
[python]: https://www.python.org/downloads/
[pip]: https://pip.pypa.io/en/stable/
[virtualenv]: https://virtualenv.pypa.io/en/stable/