Django Integration Tutorial
The Django REST Framework is a powerfull tool for building RESTful APIs based on the popular Django UI web framework. This post will demonstrate how easy it is to setup a new application using the Django framework and integrate the Shield UI JavaScript Grid component in it. The sample application will expose an API for managing a list of books and will use a local SQLite database server for persisting data. The application code is available in GitHub and can be used as a reference.
Project Setup
Creating the application
To create the Django project start with creating a directory and a virtual environment that will keep all Python dependencies isolated from the system libraries:
$ mkdir ShieldUIApp $ cd ShieldUIApp $ virtualenv env
Next use pip
to install Django and the Django Rest Framework in the local virtual environment :
$ ./env/bin/pip install django $ ./env/bin/pip install djangorestframework
The Django web framework provides a command-line utility for administrative tasks which can be used to bootstrap the project and will create all necessary files:
$ ./env/bin/django-admin startproject bookstore .
There is also a powerful and easy to use admin interface for managing the application data. In order to access it create a super user account using the manage.py
script. Before creating the super user the project database should be initialized by running the default migrations which will create all admin application tables:
$ ./env/bin/python manage.py migrate $ ./env/bin/python manage.py createsuperuser
Once the admin database and the super user account are setup create an application that will store the information for the books catalog:
$ ./env/bin/python manage.py startapp books
Setting up the database
To add the books information to the application database create a model which will describe the data that will be stored:
# books/models.py from __future__ import unicode_literals from django.db import models class Book(models.Model): title = models.CharField(max_length=200) author = models.CharField(max_length=200) rating = models.IntegerField(default=0)
and activate the model by adding the application configuration to the bookstore/settings.py
file:
# bookstore/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'books.apps.BooksConfig', ]
In order to expose the Book
model fields to the Django admin interface create a BookAdmin
representation for the Book
data:
# books/admin.py from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ('title', 'author', 'rating')
and then use the admin.site
object to register the model and its admin representation:
# books/admin.py from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ('title', 'author', ‘rating’) admin.site.register(Book, BookAdmin)
Finally the manage.py
script can be used to create the migration files and generate the database table for storing the Book
data:
$ ./env/bin/python manage.py makemigrations $ ./env/bin/python manage.py migrate
The sample application provides a JSON file that contains sample data for populating the database:
$ ./env/bin/python manage.py loaddata seed.json
To verify that everything was properly configured start the application by running the built-in server:
$ ./env/bin/python manage.py runserver Performing system checks... System check identified no issues (0 silenced).-
At this point opening http://localhost:8000/admin/ in a browser should display the admin application login prompt. After logging in as the super user the Book
model should be accessible under http://localhost:8000/admin/books/book/.
Configure the Django REST Framework
Now that the Django application is setup the Django REST Framework can be used to expose a RESTful API for managing the Book
model data. To initialize the framework application it needs to be added to the project settings:
# bookstore/settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'books.apps.BooksConfig', ]
For the sake of simplicity disable the REST API authentication:
# bookstore/settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [], 'DEFAULT_PERMISSION_CLASSES': [], }
The resource representation in the Django REST Framework is implemented by using serializers. To setup the Book
resource representation create a new books/serializer.py
file and the corresponding BookSerializer
class:
# books/serializers.py from .models import Book from rest_framework import serializers class BookSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Book fields = ('id', 'title', 'author', 'rating')
Next add a BookViewSet
class in the books/views.py
file that will use the REST framework viewsets module to define all actions for managing the Book
model records through the API:
# books/views.py from django.shortcuts import render from rest_framework import viewsets from .serializers import BookSerializer from .models import Book class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all().order_by('-id') serializer_class = BookSerializer
To expose the RESTful API endpoint create a new application specific books/urls.py
module and initialize the default router using the BookViewSet
view:
# books/urls.py from django.conf.urls import include, url from rest_framework import routers from . import views router = routers.DefaultRouter() router.register(r'catalog', views.BookViewSet) urlpatterns = [ url(r'^api/', include(router.urls)), ]
Finally to activate the new resource endpoint the books/url.py
module needs to be included in the project's bookstore/urls.py
:
# bookstore/urls.py from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^books/', include('books.urls')), ]
Once the API endpoint is properly configured it can be tested by pointing your browser to http://localhost:8000/books/api/catalog/:
Setup the Shield UI grid for rendering the data
Now that the REST API is configured and functional create a template for displaying the application index page. The template will be created in the books/templates/books
folder:
$ mkdir -p books/templates/books
and add the index.html
view:
# books/templates/books/index.html <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Shield UI and Django Integration</title> <link id="themecss" rel="stylesheet" type="text/css" href="//www.shieldui.com/shared/components/latest/css/light/all.min.css" /> <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="//www.shieldui.com/shared/components/latest/js/shieldui-all.min.js"></script> </head> <body> <h1>Shield UI Grid Example</h1> <div id="grid" style="max-width:800px; margin:auto; margin-top:40px;"></div> <script type="text/javascript"> jQuery(function($) { $("#grid").shieldGrid({ dataSource: { events: { error: function (event) { if (event.errorType == "transport") { // transport error is an ajax error; event holds the xhr object alert("transport error: " + event.error.statusText); // reload the data source if the operation that failed was save if (event.operation == "save") { this.read(); } } else { // other data source error - validation, etc alert(event.errorType + " error: " + event.error); } } }, remote: { read: { type: "GET", url: "/books/api/catalog", dataType: "json" }, modify: { create: function (items, success, error) { var newItem = items[0]; $.ajax({ type: "POST", url: "/books/api/catalog/", dataType: "json", contentType: "application/json", data: JSON.stringify(newItem.data), complete: function (xhr) { if (xhr.readyState == 4) { if (xhr.status == 201) { newItem.data.id = +xhr.responseJSON.id success(); return; } } error(xhr); } }); }, update: function (items, success, error) { $.ajax({ type: "PUT", url: "/books/api/catalog/" + items[0].data.id + '/', dataType: "json", contentType: "application/json", data: JSON.stringify(items[0].data) }).then(success, error); }, remove: function (items, success, error) { $.ajax({ type: "DELETE", url: "/books/api/catalog/" + items[0].data.id + '/' }).then(success, error); } } }, schema: { fields: { id: { path: "id", type: Number }, title: { path: "title", type: String }, author: { path: "author", type: String }, rating: { path: "rating", type: Number }, } } }, sorting: true, rowHover: false, columns: [ { field: "title", title: "Book Title" }, { field: "author", title: "Author" }, { field: "rating", title: "Rating" }, { width: 160, title: " ", buttons: [ { commandName: "edit", caption: "Edit" }, { commandName: "delete", caption: "Delete" } ] } ], toolbar: [ { buttons: [ { commandName: "insert", caption: "Add Book" } ], position: "top" } ], paging: { pageSize: 10 }, editing: { enabled: true, type: "row" } }); }); </script> </body> </html>
Rendering the index.html
template will be handled by adding an index
method in the books/view.py
module:
# books/views.py from django.shortcuts import render from rest_framework import viewsets from .serializers import BookSerializer from .models import Book class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all().order_by(‘-id’) serializer_class = BookSerializer def index(request): return render(request, 'books/index.html')
and mapping the method in the books/urls.py
module as the default application action:
# books/urls.py urlpatterns = [ url(r'^$', views.index, name='index'), url(r'^api/', include(router.urls)), ]
Now that the application index action is added and the mapping is created the books listing should be accessible through the Shield UI JavaScript Grid component on the home page.
Conclusion
The tutorial described how to create a simple Django project from scratch, setup its database and implement the Django REST Framework to expose a RESTful resource for manipulating that database. The user interface in the sample project includes the powerful Grid component from the Shield UI for JavaScript and HTML5 library that was used for rendering the data and managing the database records using the powerful server-side Django backend. By embedding powerful user interface widgets like the ones included in the Shield UI suite, developers save time, cost and concerns about client-side peculiarities like responsiveness, cross-browser support and unified product vision.
All the components included in the Shield UI framework can be seen in action here.
License Information
The Shield UI Lite library is licensed under the MIT license, details of which can be found here.
For more details about Shield UI licensing, see the Shield UI License Agreement page. Shield UI Commercial support information can be found on this page.