يوجد في نظام بايثون البيئي العديد من الأطر المتاحة لإنشاء واجهة خلفية قوية. يعد Django و FastAPI الأكثر شيوعًا. يأتي Django مزودًا بالعديد من الميزات المبتكرة مثل ORM و البرامج الوسيطة و المصادقة ولوحة الإدارة وما إلى ذلك. ومن ناحية أخرى، يأتي FastAPI مزودًا بدعم جاهز للمزامنة وهو إطار عمل فائق السرعة وخفيف الوزن لإنشاء واجهات برمجة تطبيقات Rest.
الهدف من هذه المقالة هو استكشاف كيفية الاستفادة من قوة كلا الإطارين في الإنتاج. سنقوم أولاً بإعداد تطبيق Django البسيط ثم سننتقل نحو دمج FastAPI.
ملاحظة: تفترض هذه المقالة أنك على دراية بكل من أطر العمل و SQLAlchemy واستخدمتهما في مشاريع سابقة.
جزء جانغو
سأفترض أن لديك مشروع Django الأساسي جاهزًا، إذا لم يكن الأمر كذلك. فيما يلي البرنامج التعليمي للقيام بذلك، خطواتك الأولى مع Django: إعداد مشروع Django.
أولاً سأبدأ بإنشاء تطبيق Book
django-admin startapp book
إضافة تطبيق الكتاب إلى التطبيقات المثبتة

إضافة نماذج المؤلف والكتاب
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=200)
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author,on_delete=models.CASCADE)
published_date = models.DateField()
إجراء عمليات الترحيل وترحيل التغييرات إلى قاعدة البيانات.
python manage.py makemigrations && python manage.py migrate
قد تتمكن من رؤية كلا الجدولين الجديدين مضافين ببادئات كـ app_name
في قاعدة البيانات الخاصة بك.

تأكد من إعداد هذين الجدولين. سنقوم الآن بتسجيل هذه النماذج في لوحة الإدارة وإضافة بعض كتبي المفضلة ومؤلفيها.
عينات الكتب:

المؤلفون:

أخيرًا، انتهينا من إعداد Django. و سنمضي قدمًا في إعداد FastAPI.
إعداد FastAPI
على عكس Django، يتطلب إعداد FastAPI القليل من العمل. بالنسبة للأشخاص الذين ليسوا على دراية بـ FastAPI، أوصي بمراجعة المراجع من الوثائق الرسمية قبل مواصلة المقالة.
تأكد من أن لديك الإعداد الأساسي جاهزًا لـ FastAPI وSqlalchemy مع Alembic.
وإليك كيف يبدو مشروعي:

لنبدأ بجزء قاعدة البيانات (المسمى بـ db). سنقوم بإنشاء نموذج أساسي وربط محرك قاعدة البيانات بجلسة.

هذه هي الملفات التي تتطلب عادةً البدء باتصال قاعدة البيانات.
session.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
هذا هو الإعداد المعتاد لتهيئة إعداد الجلسة، وسنقوم ببدء تشغيل البيانات الوصفية لـ sqlalchemy. تحتوي فئة البيانات الوصفية على معلومات حول كافة الجداول الموجودة في الاتصال المحدد.
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import sessionmaker
from app.core.config import settings
engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
metadata = MetaData(bind=engine)
والآن يأتي الجزء الذي قد تنتظره. إضافة نماذج! ألق نظرة على الملفات التي قمت بإنشائها. حاليا، كلا الملفين فارغان!

سنقوم باستيراد metadata
من app.db.session
والإشارة إلى الجداول الموجودة التي أنشأناها بالفعل.
books.py
from app.db.session import metadata, engine
from sqlalchemy import Table
book_table = Table('<table_name>',metadata,autoload_with=engine)
استبدل بالاسم المحدد الموجود في قاعدة البيانات. في مثالنا، سأستخدم book_book لجدول الكتاب و book_author لجدول المؤلف.
الآن الجزء الوحيد المتبقي لتعيين نموذج بالكامل هو إضافة جدول في الإعداد الخاص به.
from app.db.session import metadata, engine
from app.db.base import Base
from sqlalchemy import Table
book_table = Table('book_book',metadata,autoload_with=engine)
class Book(Base):
__table__ = book_table
author.py
from app.db.session import metadata,engine
from app.db.base import Base
from sqlalchemy import Table
author_table = Table('book_author',metadata,autoload_with=engine)
class Author(Base):
__table__ = author_table
نحن بحاجة إلى إخبار alembic بعدم القيام بأي ترحيل على هذه النماذج، حيث أن جانغو يدير هذه الكيانات. يمكنك أيضًا القيام بالعكس، ولكن أعتقد أن هذه نسخة أكثر تعقيدًا.
alembic/env.py
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
هاتان طريقتان للتشغيل وإجراء عمليات الترحيل في حالة alembic. يجب عليك تغيير الكود السابق إلى الكود الموضح أدناه.
def include_object(object, name, type_, reflected, compare_to):
if type_ == "table" and reflected and compare_to is None:
return False
else:
return True
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
include_object=include_object,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata,include_object=include_object,
)
with context.begin_transaction():
context.run_migrations()
تعمل الدالة include_object
كما يوحي الاسم على مقارنة الجداول والتسلسلات والعلاقات التي يتم اختيارها لعمليات الترحيل.
نحن نتجنب النماذج المنعكسة، أي المأخوذة من الجداول التي تمت تهيئتها بالفعل.
هذا كل شيء، أنت الآن جاهز لتشغيل واجهات برمجة التطبيقات (APIs) الخاصة بك.
uvicorn app.main:app --reload
جرب apis على مستندات api المفتوحة. سوف تحصل على نتائج مماثلة.


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