This article is the third in a series of articles. I am happy to give comprehensive tuition on building and deploying an open-source grade REST API using the Django REST framework. If you have not seen my first and second articles, kindly read the previous articles before continuing. But if you feel confident in yourself, let us ride along. These are links to the and articles. first second In this section, we shall dive straight into coding our project. But before we do that, let us learn the second approach to setting up our Django REST API project. The Second Approach of Installing Dependencies The second approach to setting up a Django REST API is great for production-grade applications. Because we intend to make this API production-grade and possibly open source, I will advise you to stick to this second approach. Open the IDE or code editor of your choice. I am using . Make sure to set the python development environment on visual studio code. Visual Studio Code Whilst at the project root directory, run the code below. code . #Take note of the period The advantage of this approach is that you will research the kind of libraries to include in your API before you begin coding. Follow the following steps to set up your project after creating the virtual-environment as we did before. # Create a workspace inside the project workspace $ touch tribal.code-workspace # For VScode environment setup # Create the requirements.txt file and list all the dependencies of the project # This makes it possible to install the listed dependencies at once. $ touch requirements.txt We know the initial dependencies we need for our API development, so let us list them in our requirements file. I also want us to install the latest long-term version of Django. Because Django is in constant development, we must lock down the version to use for the project. # Inside requirements.txt enter following dependencies django>=3.2.0,<4.0 djangorestframework pyyaml requests django-cos-headers psycopg2-binary Whilst at the root of the project folder and with the virtual environment activated, install the following requirements by the following command. # Upgrade your pip installer $ pip install --upgrade pip # Install the dependencies $ pip install -r requirements.txt Creating a PostgreSQL Database Now let's create the PostgreSQL database of our project on the terminal by running a few SQL commands. First, open the SQL shell on your terminal by entering the following command. $ sudo -u postgres psql # Create a new database at postgresql shell postgres=# create database tribalapi; # Create a user with and encrypted password # Choose appropriate namem and password postgres=# create user tribal with encrypted password 'password123'; # Now let's grant the new user all privileges to our database postgres=# grant all privileges on database tribalapi to tribal; Setting up a Django Project and Application Now, let us set up our Django project and application and register our settings file. Navigate to the directory in which you created your virtual environment, and create the Django with the following command. # Create Django project $ django-admin start project tribalproject . # Don't forget to add the period # Create Djanog app using python $ python manage.py start triabalapp # Do not include a period Configuring the Project Settings File Now, we are set to develop our models, but before that, let us register our applications in the settings.py file in our project folder. # Inside settingd.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'tribal_app', ] After you have successfully installed PostgreSQL, let me show you how to set up Django to communicate with the database using a local host. In the file, scroll to the DATABASES dictionary, and make the following changes. settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'postgres', 'USER': 'postgres', 'PASSWORD': 'password123', 'HOST': 'localhost', 'PORT': '5432', } } Do not hardcode your setup details as above, especially with a live project. You of your application if you hardcode your security details and host your code in an external repository web service like GitHub. risk the security We shall deal with not hard-coding during the securing of the application process. Models of the Tribal API A is a Python class that represents the structure and behavior of data stored in a database. They define the fields, relationships, and constraints that determine how data is stored and manipulated in the database. Django model In other words, a Django model defines the schema of a database table and provides an interface for accessing and manipulating the data stored in that table. The following code defines each table as a class and makes each field attribute of the class. I used foreign keys to define relationships between tables. from django.db import models #Create your models here. # This model translates our Regions table in the database class Region(models.Model): name = models.CharField(max_length=255) country = models.ForeignKey('Country', on_delete=models.CASCADE) def __str__(self): return self.name # This model translates our Countries table in the database class Country(models.Model): name = models.CharField(max_length=255) description = models.TextField() def __str__(self): return self.name # This model translates our Tribes table in the database class Tribe(models.Model): name = models.CharField(max_length=255) location = models.CharField(max_length=255) description = models.TextField() region = models.ForeignKey(Region, on_delete=models.CASCADE) def __str__(self): return self.name # This model translates our Traditonal Healing table in the database class HealingPractice(models.Model): name = models.CharField(max_length=255) description = models.TextField() region = models.ForeignKey(Region, on_delete=models.CASCADE) def __str__(self): return self.name # This model translates our Demorgraphy table in the database class Demography(models.Model): tribe = models.ForeignKey(Tribe, on_delete=models.CASCADE) population = models.IntegerField() language = models.CharField(max_length=255) religion = models.CharField(max_length=255) def __str__(self): return f"{self.tribe} Demography" # This model translates our Economic Activity table in the database class EconomicActivity(models.Model): tribe = models.ForeignKey(Tribe, on_delete=models.CASCADE) activity = models.CharField(max_length=255) trade = models.CharField(max_length=255) description = models.TextField() def __str__(self): return f"{self.tribe} Economic Activity" # This model translates our Environment table in the database class Environment(models.Model): name = models.CharField(max_length=255) description = models.TextField() region = models.ForeignKey(Region, on_delete=models.CASCADE) def __str__(self): return self.name # This model translates our Traditional Authority table in the database class TraditionalAuthority(models.Model): name = models.CharField(max_length=255) description = models.TextField() tribe = models.ForeignKey(Tribe, on_delete=models.CASCADE) def __str__(self): return f"{self.tribe} Traditional Authority" # This model translates our TribesRegion table in the database class TribeRegion(models.Model): tribe = models.ForeignKey(Tribe, on_delete=models.CASCADE) region = models.ForeignKey(Region, on_delete=models.CASCADE) class Meta: unique_together = ('tribe', 'region') def __str__(self): return f"{self.tribe} - {self.region}" A method is defined for each model to help with debugging and viewing and returns a string representation of the model instance. This is used when displaying the object in the Django admin UI or other parts of the app. Note that I added a constraint to the TribeRegion model metaclass, so that each tribe can only be associated with a region once. __str__ unique_together You can use Django's to interact with these models and manipulate the data in your database. Below are the models of the database tables in our API. built-in ORM Serializers of the Django REST API The Django REST Framework is a component of the Django REST Framework that provides a powerful toolkit for building web APIs. serializer Serializers are responsible for converting complex data types such as query sets and model instances into JSON or other content types over the internet. In other words, you use serializers to convert data into formats that other systems and applications can consume. It also facilitates the validation of incoming data to ensure compliance with predefined rules and restrictions before further processing. Overall, the Django REST Framework serializer is a tool for developing robust and scalable web APIs with Django, allowing easy and secure data transfer between various systems and applications. from rest_framework import serializers from .models import * # This class serializes the Region model into JSON for easy transfere class RegionSerializer(serializers.ModelSerializer): class Meta: model = Region fields = '__all__' # This class serializes the Country model into JSON for easy transfere class CountrySerializer(serializers.ModelSerializer): class Meta: model = Country fields = '__all__' # This class serializes the Tribes model into JSON for easy transfere class TribeSerializer(serializers.ModelSerializer): region = RegionSerializer() class Meta: model = Tribe fields = '__all__' # This class serializes the Traditional Healing model into JSON for easy transfere class HealingPracticeSerializer(serializers.ModelSerializer): region = RegionSerializer() class Meta: model = HealingPractice fields = '__all__' # This class serializes the Demography model into JSON for easy transfere class DemographySerializer(serializers.ModelSerializer): tribe = TribeSerializer() class Meta: model = Demography fields = '__all__' # This class serializes the Economic Activity model into JSON for easy transfere class EconomicActivitySerializer(serializers.ModelSerializer): tribe = TribeSerializer() class Meta: model = EconomicActivity fields = '__all__' # This class serializes the Environment model into JSON for easy transfere class EnvironmentSerializer(serializers.ModelSerializer): region = RegionSerializer() class Meta: model = Environment fields = '__all__' # This class serializes the Tradional Authority model into JSON for easy transfere class TraditionalAuthoritySerializer(serializers.ModelSerializer): tribe = TribeSerializer() class Meta: model = TraditionalAuthority fields = '__all__' # This class serializes the TribeRegion model into JSON for easy transfere class TribeRegionSerializer(serializers.ModelSerializer): tribe = TribeSerializer() region = RegionSerializer() class Meta: model = TribeRegion fields = '__all__' In the code above, I created a serializer class for each model. I used the ModelSerializer class provided by the Django REST Framework to generate serializer fields based on model fields. Notice that the TribeSerializer, HealingPracticeSerializer, and EnvironmentSerializer classes contain nested serializers for the Region model. You can use these serializer classes in your Django REST framework views to serialize and deserialize data from your database. Make Migrations Now I want us to make migrations of models and serializers. This step is a quick way to determine if our models and serializers are bug-free and if we have a connection with the database. Navigate to the project folder and issue the following commands at the terminal. $ python manage.py makemigrations $ python manage.py migrate Conclusion We are beginning to put shape to our API. The next part of our series will handle views and other technical details. We shall add OAuth and a third-party 0Auth2 to our API. Hopefully, we will begin to test the API in part four of our series using postman. I hope you will enjoy the read.