Reputation: 287
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.
However, these 2 specific cases result in the following error.
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
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