
في عالم البرمجة، عندما نبني تطبيقاً يتعامل مع بيانات (مثل معلومات المستخدمين أو المهام)، نحتاج إلى طريقة منظمة لتمثيل هذه البيانات. نمذجة البيانات هي عملية تحديد شكل وهيكل البيانات التي سيتعامل معها تطبيقك. بدلاً من التعامل مع البيانات كقواميس عشوائية (Dictionaries) كما تعلمنا سابقاً، نقوم بإنشاء "نماذج" (Models) تحدد بدقة ما هي الحقول المطلوبة، ونوع كل حقل، والقيم الافتراضية، والقيود.
في الدرس السابق، كنا نستقبل البيانات من المستخدم عبر FastAPI باستخدام معاملات بسيطة. لكن ماذا لو أردنا استقبال كائن كامل (مثل مهمة جديدة تحتوي على عنوان ووصف وتاريخ)؟ هنا يأتي دور Pydantic. Pydantic هي مكتبة بايثون تسمح لنا بتحديد نماذج البيانات بطريقة سهلة وقوية. فوائدها:
لنبدأ بتثبيت Pydantic (عادة ما يكون مثبتاً مع FastAPI، لكن للتأكد):
pip install pydantic
الآن، لننشئ ملفاً جديداً باسم models.py في مجلد مشروعنا. سنقوم بتعريف نموذج لمهمة (Task) بسيطة.
# models.py
from pydantic import BaseModel
from datetime import datetime
class Task(BaseModel):
title: str
description: str | None = None # حقل اختياري، قيمته الافتراضية None
is_completed: bool = False # حقل بقيمة افتراضية
created_at: datetime | None = None # حقل تاريخ اختياري
الشرح:
BaseModel: هو الفئة الأساسية التي يجب أن ترث منها جميع نماذج Pydantic.title: str: يعني أن الحقل title يجب أن يكون نصاً (string). هذا حقل إلزامي.description: str | None = None: يعني أن الحقل description يمكن أن يكون نصاً أو قيمة None (أي غير موجود). القيمة الافتراضية هي None، مما يجعله اختيارياً.is_completed: bool = False: حقل منطقي (صح/خطأ) قيمته الافتراضية False.created_at: datetime | None = None: حقل تاريخ ووقت، اختياري.الآن، لنعدل على ملف main.py الخاص بنا من الدرس السابق لاستخدام هذا النموذج.
# main.py
from fastapi import FastAPI
from models import Task # استيراد النموذج الذي أنشأناه
app = FastAPI()
# قاعدة بيانات مؤقتة (سنستخدم قاعدة بيانات حقيقية لاحقاً)
tasks_db = []
@app.post("/tasks/")
async def create_task(task: Task):
# FastAPI ستقوم تلقائياً بتحويل JSON الوارد إلى كائن Task
# والتحقق من صحة البيانات حسب النموذج
tasks_db.append(task)
return {"message": "Task created successfully", "task": task}
@app.get("/tasks/")
async def get_tasks():
return tasks_db
الشرح:
task: Task كمعامل للدالة create_task، يخبر FastAPI أن البيانات يجب أن تأتي في جسم الطلب (Request Body) وأن تكون مطابقة لنموذج Task.title)، سيرد FastAPI تلقائياً برسالة خطأ واضحة توضح المشكلة.uvicorn main:app --reload) واذهب إلى /docs. ستجد أن Swagger UI أصبح يعرف شكل البيانات المطلوبة ويعرضها لك.tasks_db لتخزين المهام. هذا ليس حلاً للإنتاج، لكنه ممتاز للتعلم والتجربة. في الدروس القادمة سنستبدلها بقاعدة بيانات حقيقية.
from pydantic import BaseModel.None.Pydantic تسمح لنا بإضافة قيود أكثر تقدماً على الحقول. على سبيل المثال، لنفرض أننا نريد التأكد من أن عنوان المهمة لا يقل عن 3 أحرف:
# models.py (محدث)
from pydantic import BaseModel, Field
from datetime import datetime
class Task(BaseModel):
title: str = Field(..., min_length=3, max_length=100, description="عنوان المهمة")
description: str | None = Field(None, max_length=500)
is_completed: bool = False
created_at: datetime | None = None
الشرح:
Field(...): النقاط الثلاث ... تعني أن الحقل إلزامي (required).min_length=3: الحد الأدنى لطول النص هو 3 أحرف.max_length=100: الحد الأقصى هو 100 حرف.Field لتوثيق نموذجك بشكل أفضل. إضافة description تجعل توثيق Swagger UI أكثر وضوحاً للمطورين الآخرين (أو لنفسك في المستقبل).
الآن حان دورك للتطبيق!
User في ملف models.py يحتوي على الحقول التالية:
username: نص، إلزامي، بطول لا يقل عن 3 ولا يزيد عن 20 حرفاً.email: نص، إلزامي. (تلميح: يمكنك استخدام EmailStr من Pydantic للتحقق من صحة البريد الإلكتروني، لكن للتبسيط استخدم str).age: عدد صحيح (int)، اختياري، بقيمة افتراضية None.main.py:
/users/POSTUser وتعيده مع رسالة ترحيبية./docs) أو باستخدام curl.بعد الانتهاء من التمرين، ستكون قد فهمت تماماً كيفية إنشاء نماذج بيانات قوية وآمنة باستخدام Pydantic، مما يضع أساساً متيناً لبناء API متكامل في الدروس القادمة.
جاري تحميل التقييمات...