01-21-2019, 06:20 PM
Build a Django RESTful API on Fedora.
<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora.png" width="750" height="421" title="" alt="" /></div><div><p>With the rise of kubernetes and micro-services architecture, being able to quickly write and deploy a RESTful API service is a good skill to have. In this first part of a series of articles, you’ll learn how to use Fedora to build a RESTful application and deploy it on Openshift. Together, we’re going to build the back-end for a “To Do” application.</p>
<p> <span id="more-23093"></span> </p>
<p>The APIs allow you to Create, Read, Update, and Delete (<a href="https://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete">CRUD</a>) a task. The tasks are stored in a database and we’re using the Django ORM (Object Relational Mapping) to deal with the database management.</p>
<h3>Django App and Rest Framework setup</h3>
<p>In a new directory, create a Python 3 virtual environment so that you can install dependencies.</p>
<pre class="wp-block-preformatted">$ mkdir todoapp && cd todoapp<br />$ python3 -m venv .venv<br />$ source .venv/bin/activate</pre>
<p>After activating the virtual environment, install the dependencies.</p>
<pre class="wp-block-preformatted">(.venv)$ pip install djangorestframework django</pre>
<p><a href="https://www.django-rest-framework.org/">Django REST Framework</a>, or DRF, is a framework that makes it easy to create RESTful CRUD APIs. By default it gives access to useful features like browseable APIs, authentication management, serialization of data, and more.</p>
<h4>Create the Django project and application</h4>
<p>Create the Django project using the django-admin CLI tool provided.</p>
<pre class="wp-block-preformatted">(.venv) $ django-admin startproject todo_app . # Note the trailing '.'<br />(.venv) $ tree .<br />.<br />├── manage.py<br />└── todo_app<br /> ├── __init__.py<br /> ├── settings.py<br /> ├── urls.py<br /> └── wsgi.py<br />1 directory, 5 files</pre>
<p>Next, create the application inside the project.</p>
<pre class="wp-block-preformatted">(.venv) $ cd todo_app<br />(.venv) $ django-admin startapp todo<br />(.venv) $ cd ..<br />(.venv) $ tree .<br />.<br />├── manage.py<br />└── todo_app<br /> ├── __init__.py<br /> ├── settings.py<br /> ├── todo<br /> │ ├── admin.py<br /> │ ├── apps.py<br /> │ ├── __init__.py<br /> │ ├── migrations<br /> │ │ └── __init__.py<br /> │ ├── models.py<br /> │ ├── tests.py<br /> │ └── views.py<br /> ├── urls.py<br /> └── wsgi.py</pre>
<p>Now that the basic structure of the project is in place, you can enable the REST framework and the <em>todo</em> application. Let’s add <em>rest_framework</em> and <em>todo</em> to the list of <em>INSTALL_APPS</em> in the project’s <em>settings.py</em>.</p>
<pre class="wp-block-preformatted">todoapp/todo_app/settings.py</pre>
<pre class="wp-block-preformatted"># Application definition<br /><br />INSTALLED_APPS = [<br /> 'django.contrib.admin',<br /> 'django.contrib.auth',<br /> 'django.contrib.contenttypes',<br /> 'django.contrib.sessions',<br /> 'django.contrib.messages',<br /> 'django.contrib.staticfiles',<br /> 'rest_framework',<br /> 'todo_app.todo',<br />]</pre>
<h3> Application Model and Database</h3>
<p>The next step of building our application is to set up the database. By default, Django uses the <span class="module__title__link">SQLite database management system. S</span>ince <span class="module__title__link">SQLite works well and is easy to use during development, let’s keep this default setting. </span>The second part of this series will look at how to replace SQLite with <span class="module__title__link">PostgreSQL to run the application in production.</span></p>
<h4>The Task Model</h4>
<p>By adding the following code to <em>todo_app/todo/models.py</em>, you define which properties have a task. The application defines a task with a <em>title, </em>a <em>description</em> and a <em>status.</em> The status of a task can only be one of the three following states: <em>Backlog, Work in Progress</em> and <em>Done.</em></p>
<pre class="wp-block-preformatted">from django.db import models<br /><br />class Task(models.Model):<br /> STATES = (("todo", "Backlog"), ("wip", "Work in Progress"), ("done", "Done"))<br /> title = models.CharField(max_length=255, blank=False, unique=True)<br /> description = models.TextField()<br /> status = models.CharField(max_length=4, choices=STATES, default="todo")<br /><br /></pre>
<p>Now create the database migration script that Django uses to update the database with changes.</p>
<pre class="wp-block-preformatted">(.venv) $ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin makemigrations</pre>
<p>Then you can apply the migration to the database.</p>
<pre class="wp-block-preformatted">(.venv) $ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin migrate</pre>
<p>This step creates a<em> </em>file named <em>db.sqlite3</em> in the root directory of the application. This is where SQLite stores the data.</p>
<h3>Access to the data</h3>
<h4>Creating a View</h4>
<p>Now that you can represent and store a task in the database, you need a way to access the data. This is where we start making use of Django REST Framework by using the <em><a href="https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset">ModelViewSet</a>. </em>The <em>ModelViewSet</em> provides the following actions on a data model: list, retrieve, create, update, partial update, and destroy.</p>
<p>Let’s add our view to <em>todo_app/todo/views.py</em>:</p>
<pre class="wp-block-preformatted">from rest_framework import viewsets<br /><br />from todo_app.todo.models import Task<br />from todo_app.todo.serializers import TaskSerializer<br /><br /><br />class TaskViewSet(viewsets.ModelViewSet):<br /> queryset = Task.objects.all()<br /> serializer_class = TaskSerializer</pre>
<h4>Creating a Serializer</h4>
<p>As you can see, the <em>TaskViewSet</em> is using a <a href="https://www.django-rest-framework.org/api-guide/serializers/">Serializer</a>. In DRF, serializers convert the data modeled in the application models to a native Python datatype. This datatype can be later easily rendered into JSON or XML,<em> </em>for example. Serializers are also used to deserialize JSON or other content types into the data structure defined in the model.</p>
<p>Let’s add our <em>TaskSerializer</em> object by creating a new file in the project <em>todo_app/todo/serializers.py</em>:</p>
<pre class="wp-block-preformatted">from rest_framework.serializers import ModelSerializer<br />from todo_app.todo.models import Task<br /><br /><br />class TaskSerializer(ModelSerializer):<br /> class Meta:<br /> model = Task<br /> fields = "__all__"</pre>
<p>We’re using the generic <em><a href="https://www.django-rest-framework.org/api-guide/serializers/#modelserializer">ModelSerializer</a></em> from DRF, to automatically create a serializer with the fields that correspond to our Task model.</p>
<p>Now that we have a data model a view and way to serialize/deserialize data, we need to map our view actions to URLs. That way we can use HTTP methods to manipulate our data.</p>
<h4>Creating a Router</h4>
<p>Here again we’re using the power of the Django REST Framework with the <em><a href="https://www.django-rest-framework.org/api-guide/routers/#defaultrouter">DefaultRouter</a></em>. The DRF <em>DefaultRouter</em> takes care of mapping actions to HTTP Method and URLs. </p>
<p>Before we see a better example of what the <em>DefaultRouter</em> does for us, let’s add a new URL to access the view we have created earlier. Add the following to <em>todo_app/urls.py</em>:</p>
<pre class="wp-block-preformatted">from django.contrib import admin<br />from django.conf.urls import url, include<br /><br />from rest_framework.routers import DefaultRouter<br /><br />from todo_app.todo.views import TaskViewSet<br /><br />router = DefaultRouter()<br />router.register(r"todo", TaskViewSet)<br /><br />urlpatterns = [<br /> url(r"admin/", admin.site.urls),<br /> url(r"^api/", include((router.urls, "todo"))),<br />]</pre>
<p>As you can see, we’re registering our <em>TaskViewSet</em> to the <em>DefaultRouter</em>. Then later, we’re mapping all the router URLs to the <em>/api</em> endpoint. This way, DRF takes care of mapping the URLs and HTTP method to our view actions (list, retrieve, create, update, destroy).</p>
<p>For example, accessing the <em>api/todo</em> endpoint with a GET HTTP request calls the list action of our view. Doing the same but using a POST HTTP request calls the create action.</p>
<p>To get a better grasp of this, let’s run the application and start using our API.</p>
<h3>Running the application</h3>
<p>We can run the application using the development server provided by Django. This server should only be used during development. We’ll see in the second part of this tutorial how to use a web server better suited for production.</p>
<pre class="wp-block-preformatted">(.venv)$ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin runserver<br />Django version 2.1.5, using settings 'todo_app.settings'<br />Starting development server at http://127.0.0.1:8000/<br />Quit the server with CONTROL-C.</pre>
<p>Now we can access the application at the following URL: <em>http://127.0.0.1:8000/api/</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora.png" alt="" class="wp-image-24543" /></figure>
<p>DRF provides an interface to the view actions, for example listing or creating tasks, using the following URL: <em>http://127.0.0.1:8000/api/todo</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora-1.png" alt="" class="wp-image-24544" /></figure>
<p>Or updating/deleting an existing tasks with this URL: <em>http://127.0.0.1:8000/api/todo/1</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora-2.png" alt="" class="wp-image-24545" /></figure>
<h3>Conclusion</h3>
<p>In this article you’ve learned how to create a basic RESTful API using the Django REST Framework. In the second part of this series, we’ll update this application to use the PostgreSQL database management system, and deploy it in OpenShift.</p>
<p>The source code of the application is available on <a href="https://github.com/cverna/django-rest-framework-todo">GitHub</a>. </p>
<p></p>
</div>
<div style="margin: 5px 5% 10px 5%;"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora.png" width="750" height="421" title="" alt="" /></div><div><p>With the rise of kubernetes and micro-services architecture, being able to quickly write and deploy a RESTful API service is a good skill to have. In this first part of a series of articles, you’ll learn how to use Fedora to build a RESTful application and deploy it on Openshift. Together, we’re going to build the back-end for a “To Do” application.</p>
<p> <span id="more-23093"></span> </p>
<p>The APIs allow you to Create, Read, Update, and Delete (<a href="https://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete">CRUD</a>) a task. The tasks are stored in a database and we’re using the Django ORM (Object Relational Mapping) to deal with the database management.</p>
<h3>Django App and Rest Framework setup</h3>
<p>In a new directory, create a Python 3 virtual environment so that you can install dependencies.</p>
<pre class="wp-block-preformatted">$ mkdir todoapp && cd todoapp<br />$ python3 -m venv .venv<br />$ source .venv/bin/activate</pre>
<p>After activating the virtual environment, install the dependencies.</p>
<pre class="wp-block-preformatted">(.venv)$ pip install djangorestframework django</pre>
<p><a href="https://www.django-rest-framework.org/">Django REST Framework</a>, or DRF, is a framework that makes it easy to create RESTful CRUD APIs. By default it gives access to useful features like browseable APIs, authentication management, serialization of data, and more.</p>
<h4>Create the Django project and application</h4>
<p>Create the Django project using the django-admin CLI tool provided.</p>
<pre class="wp-block-preformatted">(.venv) $ django-admin startproject todo_app . # Note the trailing '.'<br />(.venv) $ tree .<br />.<br />├── manage.py<br />└── todo_app<br /> ├── __init__.py<br /> ├── settings.py<br /> ├── urls.py<br /> └── wsgi.py<br />1 directory, 5 files</pre>
<p>Next, create the application inside the project.</p>
<pre class="wp-block-preformatted">(.venv) $ cd todo_app<br />(.venv) $ django-admin startapp todo<br />(.venv) $ cd ..<br />(.venv) $ tree .<br />.<br />├── manage.py<br />└── todo_app<br /> ├── __init__.py<br /> ├── settings.py<br /> ├── todo<br /> │ ├── admin.py<br /> │ ├── apps.py<br /> │ ├── __init__.py<br /> │ ├── migrations<br /> │ │ └── __init__.py<br /> │ ├── models.py<br /> │ ├── tests.py<br /> │ └── views.py<br /> ├── urls.py<br /> └── wsgi.py</pre>
<p>Now that the basic structure of the project is in place, you can enable the REST framework and the <em>todo</em> application. Let’s add <em>rest_framework</em> and <em>todo</em> to the list of <em>INSTALL_APPS</em> in the project’s <em>settings.py</em>.</p>
<pre class="wp-block-preformatted">todoapp/todo_app/settings.py</pre>
<pre class="wp-block-preformatted"># Application definition<br /><br />INSTALLED_APPS = [<br /> 'django.contrib.admin',<br /> 'django.contrib.auth',<br /> 'django.contrib.contenttypes',<br /> 'django.contrib.sessions',<br /> 'django.contrib.messages',<br /> 'django.contrib.staticfiles',<br /> 'rest_framework',<br /> 'todo_app.todo',<br />]</pre>
<h3> Application Model and Database</h3>
<p>The next step of building our application is to set up the database. By default, Django uses the <span class="module__title__link">SQLite database management system. S</span>ince <span class="module__title__link">SQLite works well and is easy to use during development, let’s keep this default setting. </span>The second part of this series will look at how to replace SQLite with <span class="module__title__link">PostgreSQL to run the application in production.</span></p>
<h4>The Task Model</h4>
<p>By adding the following code to <em>todo_app/todo/models.py</em>, you define which properties have a task. The application defines a task with a <em>title, </em>a <em>description</em> and a <em>status.</em> The status of a task can only be one of the three following states: <em>Backlog, Work in Progress</em> and <em>Done.</em></p>
<pre class="wp-block-preformatted">from django.db import models<br /><br />class Task(models.Model):<br /> STATES = (("todo", "Backlog"), ("wip", "Work in Progress"), ("done", "Done"))<br /> title = models.CharField(max_length=255, blank=False, unique=True)<br /> description = models.TextField()<br /> status = models.CharField(max_length=4, choices=STATES, default="todo")<br /><br /></pre>
<p>Now create the database migration script that Django uses to update the database with changes.</p>
<pre class="wp-block-preformatted">(.venv) $ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin makemigrations</pre>
<p>Then you can apply the migration to the database.</p>
<pre class="wp-block-preformatted">(.venv) $ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin migrate</pre>
<p>This step creates a<em> </em>file named <em>db.sqlite3</em> in the root directory of the application. This is where SQLite stores the data.</p>
<h3>Access to the data</h3>
<h4>Creating a View</h4>
<p>Now that you can represent and store a task in the database, you need a way to access the data. This is where we start making use of Django REST Framework by using the <em><a href="https://www.django-rest-framework.org/api-guide/viewsets/#modelviewset">ModelViewSet</a>. </em>The <em>ModelViewSet</em> provides the following actions on a data model: list, retrieve, create, update, partial update, and destroy.</p>
<p>Let’s add our view to <em>todo_app/todo/views.py</em>:</p>
<pre class="wp-block-preformatted">from rest_framework import viewsets<br /><br />from todo_app.todo.models import Task<br />from todo_app.todo.serializers import TaskSerializer<br /><br /><br />class TaskViewSet(viewsets.ModelViewSet):<br /> queryset = Task.objects.all()<br /> serializer_class = TaskSerializer</pre>
<h4>Creating a Serializer</h4>
<p>As you can see, the <em>TaskViewSet</em> is using a <a href="https://www.django-rest-framework.org/api-guide/serializers/">Serializer</a>. In DRF, serializers convert the data modeled in the application models to a native Python datatype. This datatype can be later easily rendered into JSON or XML,<em> </em>for example. Serializers are also used to deserialize JSON or other content types into the data structure defined in the model.</p>
<p>Let’s add our <em>TaskSerializer</em> object by creating a new file in the project <em>todo_app/todo/serializers.py</em>:</p>
<pre class="wp-block-preformatted">from rest_framework.serializers import ModelSerializer<br />from todo_app.todo.models import Task<br /><br /><br />class TaskSerializer(ModelSerializer):<br /> class Meta:<br /> model = Task<br /> fields = "__all__"</pre>
<p>We’re using the generic <em><a href="https://www.django-rest-framework.org/api-guide/serializers/#modelserializer">ModelSerializer</a></em> from DRF, to automatically create a serializer with the fields that correspond to our Task model.</p>
<p>Now that we have a data model a view and way to serialize/deserialize data, we need to map our view actions to URLs. That way we can use HTTP methods to manipulate our data.</p>
<h4>Creating a Router</h4>
<p>Here again we’re using the power of the Django REST Framework with the <em><a href="https://www.django-rest-framework.org/api-guide/routers/#defaultrouter">DefaultRouter</a></em>. The DRF <em>DefaultRouter</em> takes care of mapping actions to HTTP Method and URLs. </p>
<p>Before we see a better example of what the <em>DefaultRouter</em> does for us, let’s add a new URL to access the view we have created earlier. Add the following to <em>todo_app/urls.py</em>:</p>
<pre class="wp-block-preformatted">from django.contrib import admin<br />from django.conf.urls import url, include<br /><br />from rest_framework.routers import DefaultRouter<br /><br />from todo_app.todo.views import TaskViewSet<br /><br />router = DefaultRouter()<br />router.register(r"todo", TaskViewSet)<br /><br />urlpatterns = [<br /> url(r"admin/", admin.site.urls),<br /> url(r"^api/", include((router.urls, "todo"))),<br />]</pre>
<p>As you can see, we’re registering our <em>TaskViewSet</em> to the <em>DefaultRouter</em>. Then later, we’re mapping all the router URLs to the <em>/api</em> endpoint. This way, DRF takes care of mapping the URLs and HTTP method to our view actions (list, retrieve, create, update, destroy).</p>
<p>For example, accessing the <em>api/todo</em> endpoint with a GET HTTP request calls the list action of our view. Doing the same but using a POST HTTP request calls the create action.</p>
<p>To get a better grasp of this, let’s run the application and start using our API.</p>
<h3>Running the application</h3>
<p>We can run the application using the development server provided by Django. This server should only be used during development. We’ll see in the second part of this tutorial how to use a web server better suited for production.</p>
<pre class="wp-block-preformatted">(.venv)$ PYTHONPATH=. DJANGO_SETTINGS_MODULE=todo_app.settings django-admin runserver<br />Django version 2.1.5, using settings 'todo_app.settings'<br />Starting development server at http://127.0.0.1:8000/<br />Quit the server with CONTROL-C.</pre>
<p>Now we can access the application at the following URL: <em>http://127.0.0.1:8000/api/</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora.png" alt="" class="wp-image-24543" /></figure>
<p>DRF provides an interface to the view actions, for example listing or creating tasks, using the following URL: <em>http://127.0.0.1:8000/api/todo</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora-1.png" alt="" class="wp-image-24544" /></figure>
<p>Or updating/deleting an existing tasks with this URL: <em>http://127.0.0.1:8000/api/todo/1</em></p>
<figure class="wp-block-image"><img src="http://www.sickgaming.net/blog/wp-content/uploads/2019/01/build-a-django-restful-api-on-fedora-2.png" alt="" class="wp-image-24545" /></figure>
<h3>Conclusion</h3>
<p>In this article you’ve learned how to create a basic RESTful API using the Django REST Framework. In the second part of this series, we’ll update this application to use the PostgreSQL database management system, and deploy it in OpenShift.</p>
<p>The source code of the application is available on <a href="https://github.com/cverna/django-rest-framework-todo">GitHub</a>. </p>
<p></p>
</div>