Creating a Countries API in Django with MySQL Database
Tags: api, django, mysql, python
Published: 2023-07-19 12:14:33

**Introduction**
In this tutorial, we will walk you through the process of building a Countries API using Django, a powerful Python web framework. We will use MySQL as the database to store the information about countries and their attributes. Additionally, we'll enable searching for countries by their `id`.

**Prerequisites:**
- Python installed on your system (https://www.python.org/downloads/)
- MySQL server installed and running (https://www.mysql.com/downloads/)

Let's get started!

**Step 1: Set up a virtual environment and install Django**
Open your terminal or command prompt and create a new directory for your project:

```bash
mkdir countries_api
cd countries_api
```

**Create a virtual environment and activate it:**

```bash
python3 -m venv env

# For Windows:
. env/Scripts/activate

# For macOS/Linux:
source venv/bin/activate
```

**Install Django and Django REST framework:**

```bash
pip install django djangorestframework mysqlclient
```

**Step 2: Create a new Django project and app**

Create a new Django project and navigate into it:

```bash
django-admin startproject countries_api .
```
(Note the dot `.` at the end, which specifies the current directory as the project root.)

Create a new Django app within the project:

```bash
python manage.py startapp countries
```

**Step 3: Define the Country model**

Open the `countries/models.py` file and define the `Country` model:

```python
from django.db import models

class Country(models.Model):
    # Define the fields for the Country model
    name = models.CharField(max_length=100)
    iso3 = models.CharField(max_length=3, null=True)
    numeric_code = models.CharField(max_length=3, null=True)
    iso2 = models.CharField(max_length=2, null=True)
    phonecode = models.CharField(max_length=255, null=True)
    capital = models.CharField(max_length=255, null=True)
    currency = models.CharField(max_length=255, null=True)
    currency_name = models.CharField(max_length=255, null=True)
    currency_symbol = models.CharField(max_length=255, null=True)
    tld = models.CharField(max_length=255, null=True)
    native = models.CharField(max_length=255, null=True)
    region = models.CharField(max_length=255, null=True)
    subregion = models.CharField(max_length=255, null=True)
    timezones = models.TextField()
    translations = models.TextField()
    latitude = models.DecimalField(max_digits=10, decimal_places=8, null=True)
    longitude = models.DecimalField(max_digits=11, decimal_places=8, null=True)
    emoji = models.CharField(max_length=191, null=True)
    emojiU = models.CharField(max_length=191, null=True)
    created_at = models.DateTimeField(null=True)
    updated_at = models.DateTimeField(auto_now=True)
    flag = models.BooleanField(default=True)
    wikiDataId = models.CharField(max_length=255, null=True, db_column='wikiDataId', db_comment='Rapid API GeoDB Cities')

    def __str__(self):
        return self.name
```

**Step 4: Create the MySQL database and run migrations**

Ensure your MySQL server is running. Then, open the `countries_api/settings.py` file and update the `DATABASES` settings:

```python
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'your_mysql_db_name',
        'USER': 'your_mysql_username',
        'PASSWORD': 'your_mysql_password',
        'HOST': 'your_mysql_host',  # Use 'localhost' if the database is on the same machine
        'PORT': 'your_mysql_port',  # Typically 3306 for MySQL
    }
}
```
Replace `'your_mysql_db_name'`, `'your_mysql_username'`, `'your_mysql_password'`, `'your_mysql_host'`, and `'your_mysql_port'` with your actual MySQL database credentials.

Run the migrations to create the database tables:

```bash
python manage.py makemigrations
python manage.py migrate
```

**Step 5: Create the API views and serializers**

Open the `countries/views.py` file and define the API views:

```python
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Country
from .serializers import CountrySerializer

class CountryViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Country.objects.all()
    serializer_class = CountrySerializer

    @action(detail=True, methods=['GET'])
    def search_by_id(self, request, pk=None):
        try:
            country = Country.objects.get(pk=pk)
            serializer = CountrySerializer(country)
            return Response(serializer.data)
        except Country.DoesNotExist:
            return Response({'error': 'Country not found'}, status=404)
```

**Step 6: Register the app and REST framework in settings**

Open the `countries_api/settings.py` file and update the `INSTALLED_APPS` and `REST_FRAMEWORK` settings:

```python
# countries_api/settings.py

# ...

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'countries',
    # ...
]

# ...

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
    ],
}
```

**Step 7: Configure the URLs**

Open the `countries_api/urls.py` file and configure the URLs for the API views:

```python
# countries_api/urls.py

from django.urls import include, path
from rest_framework import routers
from countries.views import CountryViewSet

router = routers.DefaultRouter()
router.register(r'countries', CountryViewSet)

urlpatterns = [
    path('', include(router.urls)),
]
```

**Step 8: Run the development server**

Finally, run the development server:

```bash
python manage.py runserver
```

Now your Countries API is up and running! You can access it at `http://localhost:8000/countries/`. The API supports basic CRUD operations for the `Country` model and allows you to search for countries by their `id` using the `/countries/search_by_id/<id>/` endpoint.

Github link: https://github.com/sosmongare/countries_api

**Conclusion:**

In this tutorial, we have learned how to create a Countries API using Django with MySQL as the database. We have also enabled searching for countries by their `id`, making the API more powerful and flexible. By registering the app and the REST framework, we ensure that the API is properly integrated into the Django project.

Django provides a robust platform to build APIs, and MySQL offers a reliable database backend for storing your data. I hope you found this tutorial helpful in building your API. Incase of any assistance, kindly comment down.

Happy coding!