DEV Community

Cover image for How to consume RESTful APIs with Django - the easiest way
Ousseynou Diop
Ousseynou Diop

Posted on • Edited on

How to consume RESTful APIs with Django - the easiest way

Originally posted on my blog

Introduction

A REST API defines a set of functions which developers can perform requests and receive responses via HTTP protocol such as GET, POST, PUT and DELETE

Think REST API as a web service that provides you the data you want to use in your application(mobile or front-end client).

The key components for a REST API request are:

GET — The most common option, returns some data from the API based on the given endpoint.
POST — Creates a new record and add it to the database.
PUT — Update an existing record.
DELETE — Deletes the record on the given endpoint.

In this guide, we will use JSONPlaceholder API.

The final project Here

Setting up

Create a new virtual environment

mkdir use_rest_api_with_django && cd use_rest_api_with_django
virtualenv venv
Enter fullscreen mode Exit fullscreen mode

Activate our virtual environment

source /ven/bin/activate
Enter fullscreen mode Exit fullscreen mode

Install Django and requests Library

pip install Django requests
Enter fullscreen mode Exit fullscreen mode

Create a new Django project from the terminal

django-admin startproject consume_restful_api .
Enter fullscreen mode Exit fullscreen mode

Don't forget to put the dot(.) at the end.

Create a simple Django application

python manage.py startapp main_app
Enter fullscreen mode Exit fullscreen mode

Register our newly created app

# settings.py
INSTALLED_APPS = [
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'main_app.apps.MainAppConfig' # add this
]
Enter fullscreen mode Exit fullscreen mode

Change the templates directory

# settings.py
TEMPLATES = [
   {
       'BACKEND': 'django.template.backends.django.DjangoTemplates',
       'DIRS': [os.path.join(BASE_DIR, 'templates')],  # add this
       'APP_DIRS': True,
       'OPTIONS': {
           'context_processors': [
               'django.template.context_processors.debug',
               'django.template.context_processors.request',
               'django.contrib.auth.context_processors.auth',
               'django.contrib.messages.context_processors.messages',
           ],
       },
   },
]
Enter fullscreen mode Exit fullscreen mode

Inside the views.py file add this

# views.py
import requests
from django.shortcuts import render


def home(request):
   # get the list of todos
   response = requests.get('https://jsonplaceholder.typicode.com/todos/')
   # transfor the response to json objects
   todos = response.json()
   return render(request, "main_app/home.html", {"todos": todos})
Enter fullscreen mode Exit fullscreen mode

Create the required templates

mkdir templates && mkdir templates/main_app
touch templates/base.html && touch templates/main_app/home.html
Enter fullscreen mode Exit fullscreen mode

base.html

<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>How to consume RESTful APIs with Django</title>
  </head>
  <body>
    <h2>How to consume RESTful APIs with Django</h2>

    {% block content %} {% endblock content %}
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

home.html

<!-- base.html -->
{% extends "base.html" %} {% block content %}
<ul>
  {% for todo in todos %}
  <li>{{ todo.id }} - {{ todo.title }}</li>
  {% endfor %}
</ul>
{% endblock content %}
Enter fullscreen mode Exit fullscreen mode

Let's add some styling with bootstrap

Change the base.html file

<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
      integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
      crossorigin="anonymous"
    />
    <title>How to consume RESTful APIs with Django</title>
  </head>
  <body>
    <h2 class="text-center">How to consume RESTful APIs with Django</h2>

    <div class="container">
      {% block content %} {% endblock content %}
    </div>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

And home.html

<!-- home.html -->
{% extends "base.html" %}

{% block content %}
<div class="col-md-6 col-auto">
  <div class="card">
    <div class="card-header">
      Todos
    </div>
    <ul class="list-group list-group-flush">
      {% for todo in data %}
      <li class="list-group-item">{{ todo.id }} - {{ todo.title }}</li>
      {% endfor %}
    </ul>
  </div>
</div>
{% endblock content %}
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we've learned how to consume RESTful APIs with Django and Python requests Library.

Thanks for reading.

Top comments (6)

Collapse
 
alifarhad profile image
Farhad Ali

hi, thanks for this nice tuts.

I'm trying to create a REST API using Django REST API framework, but unlike a regular project, in this case project I'm required to take data from another api and then create api based on the data fetched from the first api. I'm confused how would I get this setup running? can you guide please?

Collapse
 
jairajsahgal profile image
jairajsahgal

I think you should convert the data using util.py and then transfer it using function or class

Collapse
 
shivakrishnavaraprasad profile image
shiva krishna vara prasad • Edited

hey, thanks for the clean code with nice explanation.

there is a small correction, please look at it
dev-to-uploads.s3.amazonaws.com/up...
for todo in todos. not todo in data

Collapse
 
xarala221 profile image
Ousseynou Diop

Thank you, got it.

Collapse
 
aking144 profile image
aking144

This was a good read!

There was a misspelling:
In this artilce -> In this article

Collapse
 
xarala221 profile image
Ousseynou Diop

Thank you @asking144.
I fixed it.