We have the Django welcome page working already.
I would like to create some REST services on that setup. We could make use of the Django REST framework.
Let’s keep working on our <project_root>/django_poc project to manage articles by REST. The example in this post are based on the Django REST framework quickstart tutorial. It’s good to go through all of them which could give you a more thorough idea on how the REST framework works.
1. Install the Django REST framework in your virtualenv.
pip install djangorestframework
2. Create a new app called articles.
python manage.py startapp articles
3. Configure the sqlite database in <project_root>/django_poc/settings.py.
# Database # https://docs.djangoproject.com/en/1.6/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', } }
4. Configure INSTALLED_APPS to include the Django REST framework as well as the newly created articles app. Also add the pagination setting of the REST framework.
# Application definition INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'articles', ) # REST framework REST_FRAMEWORK = { 'PAGINATE_BY': 10 }
5. Setup the articles routes in <project_root>/django_poc/urls.py.
from django.conf.urls import patterns, include, url from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^', include('articles.urls')), )
6. Let’s create the Article model.
<project_root>/django_poc/articles/models.py
from django.db import models # Create your models here. class Article(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') body = models.TextField() owner = models.ForeignKey('auth.User', related_name='articles') class Meta: ordering = ('created',)
7. Since we have setup a new model, execute syncdb again to create the article table.
python manage.py syncdb
8. Create the serializer for interconverting the article and user instance and json.
<project_root>/django_poc/articles/serializers.py
from django.forms import widgets from django.contrib.auth.models import User from rest_framework import serializers from articles.models import Article class ArticleSerializer(serializers.ModelSerializer): owner = serializers.Field(source='owner.username') class Meta: model = Article fields = ('id', 'title', 'body', 'owner',) class UserSerializer(serializers.HyperlinkedModelSerializer): # Inherit serializers.HyperlinkedModelSerializer to # hyperlink the articles to the correspongind page. articles = serializers.HyperlinkedRelatedField(many=True, view_name='article-detail') class Meta: model = User fields = ('id', 'username', 'articles')
9. Create the views by the Django REST framework ViewSet.
<project_root>/django_poc/articles/views.py
from rest_framework import permissions from rest_framework import viewsets from django.contrib.auth.models import User from articles.models import Article from articles.serializers import ArticleSerializer, UserSerializer from articles.permissions import IsOwnerOrReadOnly class ArticleViewSet(viewsets.ModelViewSet): """ This viewset automatically provides `list`, `create`, `retrieve`, `update` and `destroy` actions. """ queryset = Article.objects.all() serializer_class = ArticleSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) def pre_save(self, obj): obj.owner = self.request.user class UserViewSet(viewsets.ReadOnlyModelViewSet): """ This viewset automatically provides `list` and `detail` actions. """ queryset = User.objects.all() serializer_class = UserSerializer
10. Setup the views permissions.
<project_root>/django_poc/articles/permissions.py
from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ Custom permission to only allow owners of an object to edit it. """ def has_object_permission(self, request, view, obj): # Read permissions are allowed to any request, # so we'll always allow GET, HEAD or OPTIONS requests. if request.method in permissions.SAFE_METHODS: return True # Write permissions are only allowed to the owner of the article. return obj.owner == request.user
11. Setup the routers for the articles app.
<project_root>/django_poc/articles/urls.py
from django.conf.urls import patterns, url, include from articles import views from rest_framework.routers import DefaultRouter # Create a router and register our viewsets with it. router = DefaultRouter() router.register(r'articles', views.ArticleViewSet) router.register(r'users', views.UserViewSet) # The API URLs are now determined automatically by the router. # Additionally, we include the login URLs for the browseable API. urlpatterns = patterns('', url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) )
12. Finally we can start the application.
python manage.py runserver 0.0.0.0:8000
14. You can log in and create new article on the article listing page.
15. Here are some curl commands for testing the API.
# GET by specifying the Accept header curl http://127.0.0.1:8000/articles/ -H 'Accept: application/json' # Request JSON curl http://127.0.0.1:8000/articles/ -H 'Accept: text/html' # Request HTML # GET by format suffix curl http://127.0.0.1:8000/articles/.json # JSON suffix curl http://127.0.0.1:8000/articles/.api # Browsable API suffix (HTML) # POST using form data curl -X POST http://127.0.0.1:8000/articles/ -d "title=New Article" -d "body=Hello world" -u user:password # POST using json curl -X POST http://127.0.0.1:8000/articles/ -d '{ "title": "New Article", "body": "Hello world" }' -H "Content-Type: application/json" -u user:password
Done =)
Reblogged this on SutoCom Solutions.
LikeLike