Populating a Django Database with Data from a REST API

Prosenjeet Shil
Django Unleashed
Published in
6 min readJun 3, 2024

Integrating external data into your Django application can be a powerful way to enhance your project’s functionality and provide users with dynamic content. This process involves fetching data from an external REST API, parsing that data, and then inserting it into your Django database. By doing so, you can enrich your application with up-to-date information from various sources, improve user experience with faster load times, and ensure data availability even if the external source becomes temporarily unavailable.

In this article, we will walk you through the entire process of populating a Django database with data from a REST API. We’ll cover the following steps in detail:

  1. Setting Up Your Django Project: Creating a new Django project and app, and configuring it to handle the data.
  2. Defining the Database Model: Creating a Django model that matches the structure of the data you will fetch from the REST API.
  3. Fetching Data from the REST API: Using Python’s requests library to fetch data from an external API.
  4. Parsing and Inserting Data: Parsing the fetched data and inserting it into the Django database using Django’s ORM.
  5. Running the Command: Executing the script to populate the database and verifying the results.
  6. Displaying the Data: Creating views and templates to display the data in your application.

Why Populate a Database with External Data?

Before we dive into the technical details, let’s explore the reasons why you might want to populate your Django database with data from an external REST API:

1. Enhancing Functionality
By integrating external data, you can significantly expand the features and functionality of your application. For example, you might pull weather data, financial information, social media feeds, or any other type of data that can enrich your application’s content and provide more value to your users.

2. Improving Performance and User Experience
Fetching data from a local database is generally much faster than making repeated API calls to an external service. By storing the data locally, you can reduce latency, improve response times, and provide a smoother user experience.

3. Ensuring Data Availability and Reliability
Storing data locally ensures that your application remains functional even if the external API becomes unavailable. This can be crucial for maintaining reliability and providing a consistent user experience.

Lets Get Started
Now that we understand the benefits, let’s get started with the technical implementation. We’ll start by setting up a new Django project and app, defining our database model, and then proceed to fetch, parse, and insert data from the external REST API.

Step 1: Setting Up Your Django Project
First, ensure you have Django installed. If not, you can install it using pip:

pip install django

Now, create a new Django project and a new app within it:

django-admin startproject myproject
cd myproject
django-admin startapp myapp

Then add myapp to your project's INSTALLED_APPS in myproject/settings.py:

INSTALLED_APPS = [    
# ...
'myapp',
]

Step 2: Defining the Database Model
In myapp/models.py, define the database model that matches the structure of the data you will fetch from the REST API. For example, if you're fetching information about books, your model might look like this:

from django.db import models

class Book(models.Model):
title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
published_date = models.DateField()
isbn = models.CharField(max_length=13, unique=True)

def __str__(self):
return self.title

Now run the migrations to create the corresponding database table:

python manage.py makemigrations
python manage.py migrate

Note: Do not copy the exact model structure provided here. Adapt the model structure to match the data schema provided by the REST API you are using.

Step 3: Fetching Data from the REST API
To fetch data from the REST API, you can use Python’s requests library. If you don't have it installed, you can install it via pip:

pip install requests

Creating a Management Command
A management command in Django is a custom script that you can run using the manage.py utility. We'll create a management command to fetch data from the REST API and save it into our database.

Directory Structure
First, you need to set up the directory structure for custom management commands. Inside your Django app (myapp), create the following directories and files:

myapp/
management/
__init__.py
commands/
__init__.py
fetch_books.py

The __init__.py files are necessary to ensure Python treats the directories as packages.

Writing the Command
Now, let’s write the actual command in fetch_books.py:

  1. Import Required Modules: We need requests for making API requests and Django's BaseCommand for creating the custom command. We'll also import our Book model to interact with the database.
  2. Define the Command Class: This class inherits from BaseCommand and overrides the handle method where we will place our logic.
  3. Fetch Data from the API: Use the requests.get method to make a GET request to the API endpoint. Check if the request was successful (status code 200).
  4. Parse the JSON Data: Assuming the API returns data in JSON format, parse this data using the json method.
  5. Insert Data into the Database: Iterate over the parsed data and use Django’s ORM to insert or update the records in the database. The update_or_create method is useful here as it avoids duplicate entries based on the isbn field.

Create a new file called fetch_books.py inside management/commands:

import requests
from django.core.management.base import BaseCommand
from myapp.models import Book

class Command(BaseCommand):
help = 'Fetch data from the external API and populate the database'

def handle(self, *args, **kwargs):
response = requests.get('https://api.example.com/books')
if response.status_code == 200:
books_data = response.json()
for book in books_data:
Book.objects.update_or_create(
isbn=book['isbn'],
defaults={
'title': book['title'],
'author': book['author'],
'published_date': book['published_date'],
}
)
self.stdout.write(self.style.SUCCESS('Successfully populated the database'))
else:
self.stdout.write(self.style.ERROR('Failed to fetch data from the API'))
  • API Endpoint URL: Replace 'https://api.example.com/books' with the actual URL of the REST API you want to fetch data from.
  • API Request: The requests.get(api_url) method sends a GET request to the specified URL. The response object contains the server's response to the HTTP request.
  • Status Code Check: if response.status_code == 200: checks if the request was successful. HTTP status code 200 means the request was successful and the server returned the requested data.
  • Parsing JSON: response.json() parses the response body as JSON, converting it into a Python dictionary or list.
  • Database Insertion: Book.objects.update_or_create() updates an existing record or creates a new one if it doesn't exist. The isbn field is used to check for existing records. The defaults dictionary contains the fields to be updated or created.
  • Success and Error Messages: self.stdout.write is used to print messages to the standard output (the console).

Step 4: Running the Command
To fetch and populate the database with data from the REST API, run the custom management command:

python manage.py fetch_books

If everything is set up correctly, this command will fetch the data from the specified API endpoint, parse it, and insert it into your Django database.

Step 5: Displaying the Data
To verify that the data has been correctly inserted into your database, you can create a simple view and template to display it. In myapp/views.py, create a view to list the books:

from django.shortcuts import render
from myapp.models import Book

def book_list(request):
books = Book.objects.all()
return render(request, 'book_list.html', {'books': books})

Create a template called book_list.html in myapp/templates/:

<!DOCTYPE html>
<html>
<head>
<title>Book List</title>
</head>
<body>
<h1>Book List</h1>
<ul>
{% for book in books %}
<li>{{ book.title }} by {{ book.author }} ({{ book.published_date }})</li>
{% endfor %}
</ul>
</body>
</html>

Add a URL pattern in myapp/urls.py to map to the view:

from django.urls import path
from .views import book_list

urlpatterns = [
path('books/', book_list, name='book_list'),
]

Finally, include myapp's URLs in the project's main urls.py:

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')),
]

Now, if you start the Django development server and navigate to /books/, you should see a list of books populated from the external REST API.

Conclusion

In this article, we covered how to populate a Django database with data from an external REST API. We went through setting up the Django project, defining the database model, fetching data from the API, inserting it into the database, and displaying it in a template. This workflow is essential for integrating third-party data into your Django applications, providing richer and more dynamic content to your users. By following these steps, you can ensure that your application is both efficient and resilient, offering an enhanced user experience with dynamic, up-to-date data.

--

--

Prosenjeet Shil
Django Unleashed

Python developer sharing insights on full stack development: Python, database management, Django, DRF, React JS, and more. Follow for tips and tutorials.