Create Weather App Using Django - Step-by-Step Guide

Faraz

By Faraz -

Learn how to build a weather app using Django. This guide covers setup, API integration, styling, and error handling. Perfect for beginners.


create-weather-app-using-django-step-by-step-guide.webp

Creating a weather app is a great project for beginners to learn Django, a popular Python web framework. In this guide, we will walk you through building a weather app from scratch. You will learn how to set up your Django project, integrate the OpenWeatherMap API, handle user inputs, and style your app to make it look modern and user-friendly. By the end of this tutorial, you will have a fully functional weather application.

Setting Up Your Django Project

Installing Django

Before starting, ensure you have Python installed. You can install Django using pip:

pip install django

Creating a new Django project

Create a new Django project using the following command:

django-admin startproject weather_app

Step 1: Setting up the project structure

Navigate into your project directory:

cd weather_app

Create a Django App

Create a new app within your project:

python manage.py startapp weather

Adding the app to the project

Add weather to INSTALLED_APPS in weather_app/settings.py:

INSTALLED_APPS = [
    'weather',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Step 2: Create a Weather App

Create Forms

In weather, create a new file named forms.py and add the following function:

from django import forms

class CityForm(forms.Form):
    city = forms.CharField(max_length=100, widget=forms.TextInput(attrs={
        'class': 'form-control',
        'placeholder': 'Enter city name'
    }))

Create Views

In views.py of weather, Set up views:

from django.shortcuts import render
import requests
from .forms import CityForm

def weather_view(request):
    url = 'https://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid=YOUR_API_KEY'
    city = 'New York'
    error_message = None
    if request.method == 'POST':
        form = CityForm(request.POST)
        if form.is_valid():
            city = form.cleaned_data['city']
    else:
        form = CityForm()

    try:
        response = requests.get(url.format(city)).json()
        if response.get('cod') != 200:
            error_message = response.get('message', 'Error fetching data from OpenWeatherMap API')
            weather = None
        else:
            weather = {
                'city': city,
                'temperature': round(response['main']['temp']),
                'description': response['weather'][0]['description'],
                'icon': response['weather'][0]['icon']
            }
    except requests.exceptions.RequestException as e:
        error_message = str(e)
        weather = None

    context = {'weather': weather, 'form': form, 'error_message': error_message}
    return render(request, 'weather.html', context)

Add OpenWeatherMap API Key

Get an API key from OpenWeatherMap: OpenWeatherMap API

Replace YOUR_API_KEY in weather/views.py with your actual API key.

Create Templates

Create a new directory named weather/templates/ and add a template file weather.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Weather App</title>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;700&display=swap" rel="stylesheet">
    <style>
body {
    font-family: 'Roboto', sans-serif;
    background: linear-gradient(to right, #2980B9, #6DD5FA, #FFFFFF);
    color: #333;
    text-align: center;
    padding: 0;
    margin: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}
/* Container styling */
.container {
    background: rgba(255, 255, 255, 0.8);
    padding: 30px;
    border-radius: 15px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    max-width: 500px;
    width: 100%;
    text-align: center;
}
/* Title styling */
.title {
    font-size: 2.5em;
    margin-bottom: 20px;
    color: #2980B9;
}
/* Form styling */
form {
    margin-bottom: 20px;
}
.form-control {
    width: 80%;
    padding: 10px;
    margin-bottom: 20px;
    border: 2px solid #2980B9;
    border-radius: 10px;
    font-size: 1em;
    outline: none;
    transition: border-color 0.3s;
}
.form-control:focus {
    border-color: #6DD5FA;
}
.btn {
    padding: 10px 20px;
    border: none;
    border-radius: 10px;
    background-color: #2980B9;
    color: #fff;
    cursor: pointer;
    font-size: 1em;
    transition: background-color 0.3s;
}
.btn:hover {
    background-color: #6DD5FA;
}
/* Error message styling */
.error-message {
    margin-top: 20px;
    padding: 10px;
    background-color: #e74c3c;
    color: #fff;
    border-radius: 10px;
}
/* Weather info styling */
.weather-info {
    margin-top: 20px;
    padding: 20px;
    background: rgba(41, 128, 185, 0.1);
    border-radius: 15px;
}
.weather-details {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 20px;
}
.temp-icon {
    display: flex;
    align-items: center;
    gap: 10px;
}
.temp-icon img {
    width: 60px;
    height: 60px;
}
.temp-icon p {
    font-size: 2em;
    color: #2980B9;
}
.description {
    font-size: 1.2em;
    color: #2980B9;
}
    </style>
</head>
<body>
    <div class="container">
        <h1 class="title">Weather App</h1>
        <form method="POST">
            {% csrf_token %}
            {{ form.city }}
            <button type="submit" class="btn">Get Weather</button>
        </form>
        {% if error_message %}
        <div class="error-message">
            <p>{{ error_message }}</p>
        </div>
        {% endif %}
        {% if weather %}
        <div class="weather-info">
            <h2>{{ weather.city }}</h2>
            <div class="weather-details">
                <div class="temp-icon">
                    <img src="http://openweathermap.org/img/wn/{{ weather.icon }}@2x.png" alt="weather icon">
                    <p>{{ weather.temperature }}°C</p>
                </div>
                <p class="description">{{ weather.description }}</p>
            </div>
        </div>
        {% endif %}
    </div>
</body>
</html>

Configure URLs

In weather, create a new file named urls.py and define the URL pattern:

from django.urls import path
from . import views

urlpatterns = [
    path('', views.weather_view, name='weather'),
]

Include the app URLs in your project’s weather_app/urls.py:

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

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

Step 3: Run the Django Server

Apply Migrations:

Apply migrations to set up the database (necessary even if not using a database for this app):

python manage.py migrate

Run the Development Server:

Start the Django development server:

python manage.py runserver

Visit Your App:

Now, visit http://127.0.0.1:8000/ in your browser, and you should see the Weather App in action.

Full Weather App Project Structure

weather_app/
│
├── weather/
│   ├── migrations/
│   ├── templates/
│   │       └── weather.html
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
│
├── weather_app/
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
├── manage.py
└── requirements.txt

Conclusion

Building a weather app using Django is an excellent way to improve your coding skills and understand how web applications work. This project covered the basics of setting up a Django project, integrating with an external API, handling forms, and designing a user interface. With these skills, you can create more complex applications and explore the vast possibilities of web development with Django. Keep experimenting and building, and soon you'll be creating amazing projects!

That’s a wrap!

I hope you enjoyed this article

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post

Please allow ads on our site🥺