Django App ดึงข้อมูลสภาพอากาศผ่าน Open Weather Map API

สร้าง Django App เพื่อดึงข้อมูลสภาพอากาศผ่าน API ของ Open Weather Map

Django App ดึงข้อมูลสภาพอากาศผ่าน Open Weather Map API

ในบทความนี้จะเป็นการสร้าง Django App เพื่อดึงข้อมูลสภาพอากาศผ่าน API ของ openweathermap.org ซึ่งเปิดให้ดึง API สภาพอากาศได้ฟรีแต่ก็จะมีการจำกัดจำนวน Request ไว้ ซึ่งสามารถอ่านเพิ่มเติมในหน้าเว็บไซต์ได้เลย แต่สำหรับแพ็คเกจฟรีนั้น ก็ถือว่าเพียงพอมากแล้วครับ

ซึ่งการดึงข้อมูลจาก API มาแสดงผลหน้าเว็บ เป็นอีกหนึ่งโปรเจคท์ที่น่าสนใจสำหรับผู้เริ่มศึกษาการพัฒนาเว็บ เพราะได้เรียนรู้ทักษะในการเรียกข้อมูลมาเก็บไว้ จากนั้นก็ทำการส่งข้อมูลไปแสดงผลหน้าเว็บ ซึ่งในกระบวนการนี้จะได้เรียนรู้พื้นฐานในหลาย ๆ ส่วน

จุดประสงค์

  1. สมัครใช้งาน API ของ Open Weather Map ได้
  2. เข้าใจและสามารถดึง API (Get API) เพื่อใช้งานได้
  3. สามารถดึงข้อมูล API ผ่าน requests ไลบรารี่ของไพธอนได้
  4. เข้าใจกระบวนการในการเรียกใช้งาน API_KEY และค่าฟอร์แมตต่าง ๆ การแปลง JSON เป็น Python dict เป็นต้น

Software & Tools

สมัครใช้งาน API จาก Open Weather Map

ทำการสมัครเพื่อใช้งาน API จาก openweathermap.org โดยสามารถสมัครได้ในลิ้งค์นี้ sign-up open weather map

****

หน้าเว็บ openweathermap.org

ทำการกรอกข้อมูลให้ครบ จากนั้นก็ทำการ Sign-in เข้าใช้งาน และทำการ copy ตัว API KEY ในช่องสีแดงดังภาพด้านล่าง ซึ่งจะเก็บไว้ใช้งานต่อไป โดยเข้าไปรับ API KEY ได้ในลิ้งค์ weather api key

เข้าใช้ API KEY

สร้าง Django Weather App

เริ่มสร้าง Django project โดยแนะนำบทความด้านล่าง สามารถใช้โค้ดเดียวกัน

บทความแนะนำสำหรับ Flask

สามารถดูการสร้าง Django โปรเจคท์ได้จากบทความ Django Sitemap โดยสามารถสร้างโปรเจคท์ตามบทความนี้หรือคัดลอกโค้ดมาทำต่อได้เลย

ติดตั้ง requests เพื่อดึงข้อมูลจาก API

ติดตั้ง requests สำหรับดึงข้อมูล API จาก URL ที่ต้องการ

$ pip install requests

ทดสอบดึงข้อมูลผ่าน Python/Django Shell

ทำการทดสอบดึงข้อมูลมาแสดงผล โดยสามารถทำได้อย่างรวดเร็วใน Python Script หรือสร้างไพธอนไฟล์เพื่อทำการเขียนโค้ดตามต้องการ โดยในบทความนี้ทำผ่าน Django Shell ทำได้โดยเรียกใช้คำสั่ง python manage.py shell

$ python manage.py shell
>>> import requests
>>> url = 'http://api.openweathermap.org/data/2.5/weather?q={}&appid=26fdffdf343e3yrereferecbee53'
>>> city = 'Bangkok'
>>> weather = requests.get(url.format(city)).json()
>>> weather

จะได้ข้อมูลเป็น JSON Object และข้อมูลต่าง ๆ ที่เกี่ยวข้องกับสภาพอากาศดังผลลัพธ์ด้านล่าง

Output (JSON Object Format)

{'coord': {'lon': 100.52, 'lat': 13.75},
 'weather': [{'id': 701,
   'main': 'Mist',
   'description': 'mist',
   'icon': '50d'}],
 'base': 'stations',
 'main': {'temp': 303.83,
  'feels_like': 310.4,
  'temp_min': 301.15,
  'temp_max': 306.48,
  'pressure': 1012,
  'humidity': 83},
 'visibility': 5000,
 'wind': {'speed': 2.1, 'deg': 100},
 'clouds': {'all': 20},
 'dt': 1609209792,
 'sys': {'type': 1,
  'id': 9235,
  'country': 'TH',
  'sunrise': 1609198813,
  'sunset': 1609239569},
 'timezone': 25200,
 'id': 1609350,
 'name': 'Bangkok',
 'cod': 200}

สังเกตตรง ‘temp’: 303.83 ซึ่งตัว default จะแสดงเป็นฟอร์แมตฟาเรนไฮต์ ซึ่งถ้าอยากแปลงเป็นเซลเซียส จะอธิบายเพิ่มเติมเพิ่มเติมในส่วนของ views.py

สร้างฟังก์ชันใน views.py

ทำการสร้างฟังก์ชัน โดยในฟังก์ชันทำการประกาศตัวแปรชื่อ url ซึ่งจะใช้ในการเก็บออปเจคท์ที่ได้ทำการดึงมาจาก API

Note: API_KEY ให้ใช้ค่าจากที่ทำการคัดลอกคีย์ไว้ก่อนหน้า

app/views.py

def get_weather(request):

    # request the API data
    url = 'http://api.openweathermap.org/data/2.5/weather?q={}&&appid={API_KEY}'

    # Define the city
    city = 'Bangkok'

    # Get data wit JSON format
    weather = requests.get(url.format(city)).json() 

    # Convert JSON to Python dict, and choose  weather info
    # you want to display on HTML
    city_weather = {
        'city' : city,
        'temperature' : weather['main']['temp'],
        'humidity' : weather['main']['humidity'],
        'description' : weather['weather'][0]['description'],
        'icon' : weather['weather'][0]['icon']
    }

    # data =  weather_app
    welcome_msg = "Welcome to Django weather app"
    
    # Send data back to templates as a dict format
    context = {'city_weather' : city_weather,
               'welcome_msg': welcome_msg}

    
    return render(request, "blogapp/weather-app.html", context)

อธิบายโค้ด

city_weather จะเป็นตัวไฮไลท์สำคัญของฟังก์ชันนี้ ซึ่งจะทำการเก็บค่าข้อมูลสภาพอากาศที่ต้องการแสดงผลในหน้าเว็บ ซึ่งจะเก็บในรูปแบบของ dict ปกติคือ key-value สามารถเลือกข้อมูลที่ต้องการแสดงผลได้ตามต้องการ ซึ่งในที่นี้จะแสดงผล 5 ค่าคือ

  1. ชื่อเมือง city
  2. อุณหภูมิ temperature
  3. ความชื้น humidity
  4. คำอธิบายสภาพอากาศ description
  5. ไอค่อนแสดงสภาพอากาศ icon

Note: ตัว Default ของ temp จะมีหน่วยเป็นฟาเรนไฮต์คือจะได้ค่าประมาณ 303 F จากนั้นทำการเปลี่ยนเป็นเซลเซียสได้โดยเพิ่มพารามิเตอร์ units=metric ต่อจากชื่อเมืองเข้าไปใน URL ค่าอุณหภูมิก็จะได้ประมาณ 34 องศาเซลเซียส

ตัวอย่างเช่น

url = 'http://api.openweathermap.org/data/2.5/weather?q={}&units=metric&appid={API_KEY}'

สร้าง route ใน app/urls.py

ทำการสร้าง route เมื่อแม็ปฟังก์ชันเข้ากั URL ตามปกติ

app/urls.py

 # blogapp/urls.py       
from django.urls import path
from . import views

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

แสดงผลข้อมูลที่ดึงมาจาก API บนหน้าเว็บ

จากนั้นจะเป็นส่วนของการแสดงผลในหน้าเว็บ โดยทำการสร้างไฟล์ base.html เพื่อเป็น parent file เพื่อใช้ในการสืบทอดต่อไป จะได้ไม่ต้องเขียนหรือคัดลอกหน้า HTML เดิม ๆ ซ้ำ ๆ หลายหน้า ซึ่งนี่ก็คือ Best Practice ที่ควรปฏิบัติในส่วนของ Django Templates

base.html

<!DOCTYPE html>
<html>
<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    {% block title %} {% endblock title %}
</head>
<body>
    {% block content %} {% endblock content %}
</body>
</html>

ทำการสืบทอด (Inherit) จากไฟล์ base.html ที่ได้สร้างเป็น parent file ไว้ก่อนหน้า โดยใช้ Django Template Tag คือ {% extends “parent-file” %}

หลังจากนั้นก็สามารถกำหนดการแสดงผลในรูปแบบของ Variables ใน Django โดยใช้ {{variable}} ซึ่งถ้าจะแสดงข้อความต้อนรับก็เรียกใช้ {{ welcome_msg }} dfdfdนอกจากนั้นก็แสดงผลสภาพอากาศตามที่กำหนดไว้ใน views.py ของแต่ละคีย์ที่ต้องการ ไม่ว่าจะเป็น city , icon , temperature ,

humidity โดยสามารถเข้าถึงโดยเรียกใช้ city_weather ซึ่งเป็นคีย์ตัวหลักก่อนและตามด้วย . (Dot Notation) ก็จะได้ Django Variable เช่น {{ city_weather.temperature }} ก็จะได้เป็นอุณหภูมิ ซึ่งอยากแสดงผลตัวอื่น ๆ ก็ใช้แนวคิดเดียวกัน

weather.html

{% extends "blogapp/base.html" %}

{% block title %}<title>Weather App</title>{% endblock title %}

{% block content %} 
    <div class="container">
        <br>
        <h1 style="font-size: 24px;">{{ welcome_msg }}</h1>
        <div class="card border-secondary mb-3" style="max-width: 18rem;">
            <div style="text-align: center;">
                <img src="http://openweathermap.org/img/w/{{ city_weather.icon }}.png" alt="weather-app-django" width="60px" height="80px">
            </div>
            <div class="card-header">{{ city_weather.city }}</div>
            <div class="card-body text-secondary">
              <h5 class="card-title">อุณหภูมิ: {{ city_weather.temperature }} C ํ</h5>
              <p class="card-text">ความชื้นสัมพัทธ์: {{ city_weather.humidity }}</p>
              <p class="card-text">สภาพอากาศเป็นอย่างไรบ้าง: {{ city_weather.description }}</p>
            </div>
        </div>
    </div>
{% endblock content %}

ทำการรีเฟรชหน้าเว็บ จะได้ผลลัพธ์ด้านข้อมูลสภาพอากาศของกรุงเทพ ฯ แสดงผลได้ตามต้องการ

จะได้ข้อมูลสภาพอากาศของกรุงเทพ ฯ แสดงผลบนหน้าเว็บ

สำหรับบทความ สร้าง Django App เพื่อดึงข้อมูล API สภาพอากาศแสดงผลในหน้าเว็บ ก็ขอจบลงเพียงเท่านี้ หวังว่าจะเป็นประโยชน์ไม่มากก็น้อย ถ้ามีข้อแนะนำหรือเสนอแนะตรงไหนหรืออยากแลกเปลี่ยนความคิดเห็นตรงส่วนไหน ก็สามารถคอมเมนต์ได้ที่คอมเมนต์ด้านล่างได้เลยครับ พบกันกับบทความถัดไป

Follow us on

Medium: STACKPYTHON

Youtube: STACKPYTHON

https://www.youtube.com/c/stackpython/videos

| Like | Comment | Share | >> STACKPYTHON

References

[ Open Weather Map] - openweathermap.org

[ Digital Ocean] - How to build a weather app in Django