البرمجة

تطوير تطبيق الطقس بجانغو

بناء تطبيق يعرض أحوال الطقس باستخدام جانغو Django

في عصرنا الرقمي الحالي، أصبحت تطبيقات الطقس من بين أكثر التطبيقات استخدامًا على الهواتف الذكية والمواقع الإلكترونية، لما لها من أهمية كبيرة في توفير المعلومات الدقيقة حول حالة الطقس للمستخدمين. من بين الأُطُر البرمجية (frameworks) المستخدمة في تطوير تطبيقات الويب، تبرز جانغو Django كواحدة من أكثر الأُطُر شعبية وكفاءة. هذا المقال يقدم شرحًا مفصلًا وشاملًا لبناء تطبيق يعرض أحوال الطقس باستخدام جانغو، مع التركيز على أهم الخطوات التقنية والبرمجية، إلى جانب شرح مفصل لكيفية التعامل مع واجهات برمجة التطبيقات API لجلب بيانات الطقس الحقيقية، وتصميم واجهة المستخدم، إضافة إلى تحسين التطبيق من حيث الأداء والأمان.


مقدمة حول جانغو Django

جانغو هو إطار عمل مفتوح المصدر يعتمد على لغة بايثون Python لتطوير تطبيقات الويب بطريقة سريعة، منظمة وقابلة للتطوير. يتميز جانغو بتوفير أدوات جاهزة تتيح للمطورين بناء مواقع وتطبيقات معقدة بسهولة، بفضل توفيره نظام نماذج قواعد بيانات متكامل، نظام توجيه URLs، ونظام نماذج عرض Views، إضافة إلى واجهات تحكم إدارية جاهزة.

في بناء تطبيق يعرض أحوال الطقس، سيساعدنا جانغو على إدارة الطلبات القادمة من المستخدم، الاتصال بواجهات APIs الخارجية التي توفر بيانات الطقس، وتنظيم هذه البيانات لعرضها بشكل مبسط وواضح في واجهة المستخدم.


الخطوة الأولى: الإعدادات الأولية للمشروع

لبداية المشروع، من الضروري التأكد من توفر بيئة تطوير مناسبة تحتوي على بايثون Python وجانغو Django. يمكن تثبيت جانغو باستخدام مدير الحزم pip عبر الأمر التالي:

bash
pip install django

بعد تثبيت جانغو، يتم إنشاء مشروع جديد باستخدام الأمر:

bash
django-admin startproject weather_project

هذا الأمر يُنشئ هيكل المشروع الأساسي، الذي يحتوي على ملفات الإعدادات الرئيسية، ملفات التوجيه، وملفات إدارة قواعد البيانات.


إنشاء تطبيق الطقس داخل المشروع

جانغو يعتمد على مفهوم التطبيقات Apps داخل المشروع، وهي وحدات مستقلة تقوم بوظائف محددة. لبناء تطبيق الطقس، ننشئ تطبيق جديد داخل المشروع الرئيسي:

bash
cd weather_project python manage.py startapp weather

بهذا الشكل يكون لدينا تطبيق باسم weather مخصص لإدارة كافة عمليات الطقس داخل الموقع.


دمج تطبيق الطقس في إعدادات المشروع

يجب إضافة تطبيق weather إلى قائمة التطبيقات المثبتة في ملف الإعدادات settings.py:

python
INSTALLED_APPS = [ # التطبيقات الافتراضية 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # تطبيق الطقس الخاص بنا 'weather', ]

تصميم نموذج البيانات Model

عادة، تطبيقات الطقس لا تحتاج إلى تخزين بيانات الطقس في قاعدة البيانات، بل تعتمد على جلبها مباشرة من خدمات خارجية. ومع ذلك، يمكننا تصميم نموذج بسيط لتسجيل المدن التي يفضلها المستخدم، أو حفظ آخر بحث قام به، لتعزيز تجربة المستخدم.

مثال على نموذج بسيط لتخزين أسماء المدن:

python
from django.db import models class City(models.Model): name = models.CharField(max_length=100, unique=True) def __str__(self): return self.name

بعد تصميم النموذج، يتم إنشاء وتطبيق الترحيلات:

bash
python manage.py makemigrations python manage.py migrate

التعامل مع API الطقس لجلب البيانات الحية

هناك العديد من خدمات API التي توفر بيانات الطقس مثل OpenWeatherMap وWeatherAPI وAccuWeather. في هذا المقال، سنستخدم OpenWeatherMap لأنها مجانية نسبيًا وسهلة الاستخدام.

التسجيل والحصول على مفتاح API

للحصول على مفتاح API يجب التسجيل في موقع OpenWeatherMap من خلال الرابط: https://openweathermap.org

بعد التسجيل، سيتم منح مفتاح API مميز يجب حفظه لاستخدامه في تطبيقنا.

إرسال طلب لجلب بيانات الطقس

تقوم خدمة OpenWeatherMap بتوفير بيانات الطقس عبر إرسال طلب HTTP GET إلى رابط محدد مع تضمين اسم المدينة ومفتاح API.

مثال للرابط:

bash
http://api.openweathermap.org/data/2.5/weather?q=London&appid=YOUR_API_KEY&units=metric
  • q=London: اسم المدينة المطلوبة.

  • appid=YOUR_API_KEY: مفتاح API الخاص بك.

  • units=metric: وحدة قياس درجة الحرارة (مئوية).


كتابة كود جلب بيانات الطقس في جانغو

في ملف views.py داخل تطبيق weather، نكتب دالة تستقبل اسم المدينة وتقوم بجلب بيانات الطقس.

python
import requests from django.shortcuts import render from .models import City API_KEY = 'YOUR_API_KEY' def weather_view(request): city = request.GET.get('city', 'Cairo') # القيمة الافتراضية: القاهرة url = f'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric' response = requests.get(url) data = response.json() if data.get('cod') != 200: weather_data = None else: weather_data = { 'city': city, 'temperature': data['main']['temp'], 'description': data['weather'][0]['description'], 'icon': data['weather'][0]['icon'], 'humidity': data['main']['humidity'], 'pressure': data['main']['pressure'], 'wind_speed': data['wind']['speed'], } context = { 'weather': weather_data } return render(request, 'weather/weather.html', context)

في هذا الكود:

  • نستقبل اسم المدينة من خلال طلب GET، وإذا لم يُرسل يُستخدم اسم “القاهرة” افتراضياً.

  • نرسل طلب إلى API باستخدام مكتبة requests.

  • نتحقق من حالة الرد ونستخرج المعلومات المهمة.

  • نمرر البيانات إلى القالب weather.html لعرضها.


إعداد ملف القوالب Templates

يجب إنشاء مجلد templates داخل مجلد تطبيق weather، ثم إنشاء ملف weather.html لعرض البيانات.

هيكلة المجلدات:

markdown
weather/ templates/ weather/ weather.html

محتوى الملف weather.html يمكن أن يكون كالتالي:

html
html> <html lang="ar"> <head> <meta charset="UTF-8"> <title>تطبيق الطقسtitle> <style> body { font-family: Arial, sans-serif; background: linear-gradient(to right, #2980b9, #6dd5fa, #ffffff); color: #333; margin: 0; padding: 20px; } .weather-container { max-width: 400px; background: #fff; padding: 15px 30px; margin: auto; border-radius: 10px; box-shadow: 0 0 15px rgba(0,0,0,0.1); } h1 { text-align: center; margin-bottom: 20px; } .weather-info { text-align: center; } .weather-info img { width: 100px; } .form-search { text-align: center; margin-bottom: 20px; } input[type="text"] { padding: 8px; width: 70%; font-size: 16px; } input[type="submit"] { padding: 8px 15px; font-size: 16px; cursor: pointer; background-color: #2980b9; border: none; color: white; border-radius: 4px; } style> head> <body> <div class="weather-container"> <h1>حالة الطقسh1> <form method="get" class="form-search"> <input type="text" name="city" placeholder="أدخل اسم المدينة" required> <input type="submit" value="عرض الطقس"> form> {% if weather %} <div class="weather-info"> <h2>{{ weather.city }}h2> <img src="http://openweathermap.org/img/wn/{{ weather.icon }}@2x.png" alt="icon"> <p>درجة الحرارة: {{ weather.temperature }}°مp> <p>الوصف: {{ weather.description }}p> <p>الرطوبة: {{ weather.humidity }}%p> <p>الضغط الجوي: {{ weather.pressure }} hPap> <p>سرعة الرياح: {{ weather.wind_speed }} متر/ثانيةp> div> {% else %} <p>لا توجد بيانات للمدينة المطلوبة.p> {% endif %} div> body> html>

إعداد ملف التوجيه URLs

يجب ربط دالة العرض weather_view في ملف urls.py داخل تطبيق weather:

python
from django.urls import path from .views import weather_view urlpatterns = [ path('', weather_view, name='weather'), ]

كما يجب ربط مسار التطبيق في ملف urls.py الخاص بالمشروع الرئيسي weather_project/urls.py:

python
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('weather.urls')), ]

التعامل مع متطلبات الأمان وتحسين التطبيق

  • إخفاء مفتاح API: من الممارسات الجيدة عدم وضع مفتاح API بشكل مباشر في الكود، بل يمكن وضعه في ملف إعدادات البيئة .env واستخدام مكتبة python-dotenv لقراءة القيم بأمان.

  • التعامل مع الأخطاء: يجب تحسين الكود للتعامل مع الأخطاء الناتجة عن عدم اتصال API أو وجود أخطاء في البيانات، بحيث يظهر للمستخدم رسالة مناسبة دون توقف التطبيق.

  • التحسين من تجربة المستخدم: إضافة مميزات مثل حفظ آخر المدن التي تم البحث عنها، أو اقتراح أسماء مدن أثناء الكتابة يمكن أن يعزز من التفاعل.


توسيع التطبيق: عرض الطقس في عدة مدن وحفظ تاريخ البحث

يمكن تطوير التطبيق ليعرض حالة الطقس لعدة مدن محفوظة في قاعدة البيانات، مما يسمح للمستخدم بالاطلاع على حالة الطقس لأماكن متعددة.

مثال لكود دالة العرض التي تعرض الطقس لعدة مدن:

python
def weather_multiple_cities(request): cities = City.objects.all() weather_data = [] for city in cities: url = f'http://api.openweathermap.org/data/2.5/weather?q={city.name}&appid={API_KEY}&units=metric' response = requests.get(url) data = response.json() if data.get('cod') == 200: weather_data.append({ 'city': city.name, 'temperature': data['main']['temp'], 'description': data['weather'][0]['description'], 'icon': data['weather'][0]['icon'], }) context = { 'weather_data': weather_data } return render(request, 'weather/multiple_weather.html', context)

وفي هذا السيناريو، يتم بناء صفحة تعرض الطقس لجميع المدن المخزنة.


استخدام الجدول لعرض بيانات الطقس

لتسهيل قراءة البيانات بشكل منظم، يمكن استخدام جدول HTML لعرض بيانات الطقس لعدة مدن. مثال على تصميم الجدول في القالب multiple_weather.html:

html
<table border="1" cellpadding="10" cellspacing="0" style="margin:auto; width:80%; border-collapse: collapse;"> <thead style="background-color:#2980b9; color:#fff;"> <tr> <th>المدينةth> <th>درجة الحرارة (°م)th> <th>الوصفth> <th>الأيقونةth> tr> thead> <tbody> {% for weather in weather_data %} <tr> <td>{{ weather.city }}td> <td>{{ weather.temperature }}td> <td>{{ weather.description }}td> <td><img src="http://openweathermap.org/img/wn/{{ weather.icon }}.png" alt="icon">td> tr> {% endfor %} tbody> table>

ملخص تقني للمشروع

الخطوة الوصف
تثبيت جانغو استخدام pip install django لإنشاء بيئة تطوير جانغو
إنشاء المشروع أمر django-admin startproject weather_project
إنشاء التطبيق أمر python manage.py startapp weather
إعداد قاعدة البيانات إنشاء نموذج City لحفظ أسماء المدن
ربط التطبيق إضافة weather في INSTALLED_APPS
التعامل مع API استخدام مكتبة requests لجلب بيانات الطقس من OpenWeatherMap
تصميم القوالب إنشاء ملفات HTML لعرض الطقس مع تصميم بسيط وجذاب
التوجيه URLs ربط العناوين بـ views لتقديم بيانات الطقس
تحسين الأمان إخفاء مفتاح API والتعامل مع الأخطاء بشكل مناسب
توسيع التطبيق عرض الطقس لعدة مدن وحفظ تاريخ البحث

خاتمة تقنية

تطبيق الطقس باستخدام جانغو هو مشروع عملي مثالي يجمع بين التعامل مع البيانات الحية من الإنترنت، تصميم قواعد بيانات بسيطة، بناء واجهات مستخدم واضحة، وتحسين تجربة المستخدم بميزات متعددة. يوفر جانغو الأدوات اللازمة لبناء هذا النوع من التطبيقات بكفاءة عالية، مع قابلية للتطوير والتخصيص حسب الاحتياجات المستقبلية.

باتباع الخطوات الموضحة، يمكن لأي مطور متوسط المستوى بناء تطبيق طقس متكامل، يوفر معلومات دقيقة وموثوقة للمستخدمين، مع إمكانية التوسع والتحسين المستمر باستخدام أدوات جانغو المتنوعة.