IOIOIOIOIOIOI
IOIOIOIOIOIOI

Reputation: 287

Django GET request result for data not in API

Context

I am using django to take user input via a form. This data, city_name, is then used to call an API for weather data.

The request works fine when an actual city name is given.


Blocker/Obstacles

However, these 2 specific cases result in the following error.

  1. Invalid city name
  2. Search button is clicked without entering anything into the form enter image description here

I have tried using some conditional logic to no avail.
Any help will be greatly appreciated.

Views.py

from django.shortcuts import render
import requests

def index(request):
    if 'city' in request.GET:
        city = request.GET['city']

        # Query API with user input 
        payload = {'q': request.GET['city'], 'appid': 'API_KEY'}
        response = requests.get('http://api.openweathermap.org/data/2.5/weather', params=payload)

        # Parse json output for key value pairs 
        e = response.json()

        context = {
            'city_name': e['name'], 
            'weather':e['weather'][0]['main'],
            'description' : e['weather'][0]['description'],
            'temp' : e['main']['temp'],
            'pressure':e['main']['pressure'],
            'humidity':e['main']['humidity'],
            'visibility':e['visibility'],
            'wind_speed':e['wind']['speed'],
            'wind_deg':e['wind']['deg']
            }

        # successfull response code
        search_was_successful = (response.status_code == 200)  # 200 = SUCCESS
        context['success'] = search_was_successful
        
        return render(request, 'index.html', {'context': context}) 

    else:
        context = None
        return render(request, 'index.html', context)

HTML(index.html)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WeatherApp</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/5.0.0-alpha1/css/bootstrap.min.css">
</head>
<body>
<div align="center">
<h1>Weather in your city</h1>
    <form action="" method="get">
        <input type="text" id="city" name="city" placeholder="Enter a city">
        <input type="submit" name="send" value="Search">
    </form>
    {% if context %}
        {% if context.success %}
            <p>
                <h3>The weather in {{context.city_name}} is:</h3>
                <div>Weather: {{context.weather}}</div>
                <div>Weather description: {{context.description}}</div>
                <div>Temperature: {{context.temp}} <sup>o</sup>C</div>
                <div>Pressure: {{context.pressure}} hPa</div>
                <div>Humidity: {{context.humidity}} %</div>
                <div>Visibility: {{context.visibility}} m</div>
                <div>Wind Speed: {{context.wind_speed}} meter/sec</div>
                <div>Wind Degrees: {{context.wind_deg}} <sup>o</sup></div>
                <div>Conn: {{context.success}} <sup>o</sup></div>
            </p>
        {% else %}
        <p><em>This doesn't work</em></p>
        {% endif %}
    {% endif %}
</div>
</body>
</html>

Upvotes: 0

Views: 443

Answers (1)

monwisn
monwisn

Reputation: 36

To validate incorrectly entered data or an empty string you can use something like this: ...

    e = response.json()

    if e['cod'] == "404" or city == "":
        messages.info(request, 'Incorrect city name, try again.') # or print something 
    else:
        context = {
        'city_name': e['name'], 
        'weather':e['weather'][0]['main'],
        'description' : e['weather'][0]['description'],
        'temp' : e['main']['temp'],
        'pressure':e['main']['pressure'],
        'humidity':e['main']['humidity'],
        'visibility':e['visibility'],
        'wind_speed':e['wind']['speed'],
        'wind_deg':e['wind']['deg']
        }

Remember: If you want to use messages in your code, you also need to add information in the html file at the beginning of the body part:

{% if messages %}
    {% for message in messages %}
        <div class="alert {{ message.tags }} alert-dismissible" role="alert">
            <button type="button" class="btn-close" data-dismiss="alert" aria-label="Close"></button>
            {{ message|striptags|safe|linebreaksbr }}
        </div>
    {% endfor %}
{% endif %}

Upvotes: 1

Related Questions