Building a Currency Converter in Django: A Step-by-Step Guide
Tags: django, currencyconverter, python, tutorials
Published: 2023-11-17 11:28:17

In today's interconnected world, handling currency conversion is a common requirement for many web applications. In this tutorial, we will walk through the process of building a simple currency converter using Django, a powerful Python web framework. By the end of this guide, you'll have a functional currency converter that users can interact with.

**Prerequisites**
Before we start, ensure you have the following installed on your system:

- Python
- Django

You can install Django using the following command:

```bash
pip install python
pip install django
```
**Setting Up the Django Project**

Let's begin by creating a new Django project. Open your terminal and run the following commands:

```bash
django-admin startproject currency_converter
cd currency_converter
```
Next, create a new Django app within the project:

```bash
python manage.py startapp converter
```

**Building the Views**
Define the views in the views.py file of the converter app:

```bash
from django.shortcuts import render
import requests

def get_currency_data():
    """ Fetch currency data from the API """
    url = "https://open.er-api.com/v6/latest/USD"
    try:
        response = requests.get(url)
        response.raise_for_status()
        currency_data = response.json()
        return currency_data
    except requests.exceptions.RequestException as e:
        print(f"Error fetching currency data: {e}")
        return None
    except ValueError as e:
        print(f"Error decoding JSON response: {e}")
        return None

def index(request):
    currency_to = "USD"
    result = None

    if request.method == "POST":
        try:
            amount = float(request.POST.get('amount'))
            currency_from = request.POST.get("currency_from")
            currency_to = request.POST.get("currency_to")
        except (ValueError, TypeError):
            result = "Invalid input"
        else:
            url = f"https://open.er-api.com/v6/latest/{currency_from}"
            try:
                response_data = requests.get(url).json()
                if "result" in response_data and response_data["result"] == "success":
                    rates = response_data.get("rates", {})
                    ex_target = rates.get(currency_to)
                    if ex_target is not None:
                        result = "{:.2f}".format(ex_target * amount)
                    else:
                        result = "Currency not found"
                else:
                    result = "Error fetching exchange rates"
            except requests.exceptions.RequestException as e:
                result = f"API request failed: {e}"

    context = {
        "result": result,
        "currency_to": currency_to,
        "currency_data": get_currency_data()
    }

    return render(request, "index.html", context)

```

**Creating Templates**
Create two HTML templates: base.html

```bash
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="icon" href="images/favicon.png" type="image/png">
    <title>{% block title %} {% endblock title %} - Converter </title>

    <link rel="stylesheet" href="static/css/font-awesome.min.css"> 
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

    <link rel="stylesheet" href="static/css/style_1.css">
</head>

<body>

    <header class="header_area">
        <div class="main_menu">
            <nav class="navbar navbar-expand-lg navbar-light">
                <div class="container">
                    <a class="navbar-brand logo_h" href="/">
                        ExchangeX
                        <!-- <img src="" height="70" alt> -->
                    </a>
                    <button class="navbar-toggler" type="button" data-toggle="collapse"
                        data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>

                    <div class="collapse navbar-collapse offset" id="navbarSupportedContent">
                        <ul class="nav navbar-nav menu_nav justify-content-end">
                            <li class="nav-item"><a class="nav-link" href="https://rohitashsingh.vercel.app"
                                    target="_blank">About</a></li>
                        </ul>
                    </div>
                </div>
            </nav>
        </div>
    </header>


    {% block body %}

    {% endblock body %}


    <footer class="footer_area">
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-lg-12">
                    <div class="footer_top flex-column">
                        <div class="footer_logo">
                            <a href="/">
                                <h1>ExchangeX</h1>
                            </a>
                            <h4>Follow Us</h4>
                        </div>
                        <div class="footer_social">
                            <a href="https://facebook.com/timrock89"><i class="fa fa-facebook"></i></a>
                            <a href="https://twitter.com/rohitashsingh89"><i class="fa fa-twitter"></i></a>
                            <a href="https://github.com/rohitashsingh89"><i class="fa fa-github"></i></a>
                        </div>
                    </div>
                </div>
            </div>
            <div class="row footer_bottom justify-content-center">
                <p class="col-lg-8 col-sm-12 footer-text">

                    Copyright ©
                    <script>document.write(new Date().getFullYear());</script> All rights reserved!! <br> Designed with
                    <i class="fa fa-heart-o text-danger" aria-hidden="true"></i> by <a
                        href="https://rohitashsingh.vercel.app" target="_blank">Rohitash Singh</a>
                </p>
            </div>
        </div>
    </footer>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js"
        integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js"
        integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+"
        crossorigin="anonymous"></script>

    <link rel="stylesheet" href="static/js/script.js">


</body>

</html>

```

index.html

```bash
{% extends 'base.html' %}
{% load static %}
{% block title %} Home {% endblock title %}
{% block body %}

<section style="padding-top: 20vh;">
  <div class="container text-center">
    <h1 class="text-dark mb-5">
      Foreign Currency Exchange Rate Converter

    </h1>
  </div>
</section>

<div class="container">
  <div class="row mx-auto">
    <div class="col-lg-12">
      <div>
        <form method="post" class="p-2" style="box-shadow: 0 2px 5px 0 rgb(0 0 0 / 16%), 0 2px 10px 0 rgb(0 0 0 / 12%);"
          action="{% url 'index' %}">
          {% csrf_token %}
          <div class="header text-center mb-5">
            We Use Mid-Market Exchange Rates
          </div>
          <div class="d-flex justify-content-between align-items-center px-5">
            <div class="my-auto">
              <label>Amount</label> <br>
              <input type="text" class="form-control" name="amount" id="amount" placeholder="Amount">
            </div>

            <div class="left-column">
              <div>
                <label>From</label>
                <div>
                  <select id="currency_from" name="currency_from">
                    {% for currency_code, currency_rate in currency_data.rates.items %}
                    <option value="{{ currency_code }}">{{ currency_code }}</option>
                    {% endfor %}
                  </select>

                </div>
              </div>

            </div>

            <a href="javascript:void(0);" role="button" class="swap-btn" aria-label="swap-button" onclick="swapValues()"
              title="swap" style="width: 74px;">⇄</a>

            <div class="right-column max-height: 150px;">
              <div>
                <label>To</label>
                <div style=" overflow-y: auto;">
                  <select id="currency_from" name="currency_to" class="selectpicker" data-live-search="true"
                    data-size="5">
                    {% for currency_code, _ in currency_data.rates.items %}
                    <option value="{{ currency_code }}">{{ currency_code }}</option>
                    {% endfor %}
                  </select>
                </div>
              </div>
            </div>
          </div>

          <div class="footer text-center my-3 mt-5">
            <input type="submit" value="Convert" class="btn btn-primary">
          </div>

          <h2 class="text-center my-3">{{ result }} {{ currency_to }}</h2>
        </form>

        <div class="error" id="formErrorBlock" style="display: none">
          <h3 id="formErrorMsg"></h3>
        </div>

        <br>
      </div>
    </div>
  </div>
</div>


{% endblock body %}

```

**Building Urls**

```bash

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

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

```
please write css according to your requirements or design pattern.

This is how we learn how to create currency converter in python.
Feel free to make it super advance. You can store exchange rate in database and many more.
Thank you for reading my Blog.

Happy Coding!.