جانغو Django هو إطار عمل ويب عالي المستوى مجاني ومفتوح المصدر ومكتوب بلغة البرمجة بايثون Python، ويُستخدَم على نطاق واسع لبناء تطبيقات ويب معقدة، وهو معروف بقدرته على التعامل مع حركة المرور العالية وميزات الأمان الخاصة به ومكوناته القابلة لإعادة الاستخدام.
يتبع جانغو نمط معمارية نموذج-عرض-متحكم Model-View-Controller أو MVC اختصارًا ويأتي مع واجهة مُدمَجة لإدارة الموقع مع دعم الاستيثاق Authentication وربط الكائنات بالعلاقات Object-Relational Mapping أو ORM اختصارًا الذي يسمح بتعريف مخطط قاعدة بياناتك باستخدام أصناف Classes بايثون.
يتمتع جانغو بمجتمع كبير ونشط يوفر مجموعة كبيرة من البرامج التعليمية والحزم والموارد الأخرى التي يمكن للمطورين استخدامها، إذ تُبنَى العديد من المواقع الإلكترونية المعروفة وذات حركة المرور العالية -مثل إنستغرام Instagram وبنترست Pinterest وموقع واشنطن تايمز The Washington Times- باستخدام إطار عمل جانغو. يُعَد جانغو أحد أكثر أطر عمل الويب شعبيةً وقوة للغة بايثون، وتستخدمه كلٌّ من الشركات الناشئة والكبيرة على نطاق واسع، مما يجعله خيارًا رائعًا لبناء تطبيقات ويب قوية وقابلة للتوسّع، وتؤدي مرونته وقابليته للتوسع إلى جعله الخيار الأفضل للمطورين والمؤسسات التي تريد إنشاء تطبيقات ويب معقدة وصغيرة الحجم.
هذه المقالة جزء من سلسلة من المقالات تشرح جانغو للمبتدئين على النحو التالي:
- البدء في إنشاء مدونة بسيطة
- استخدام بنية MTV لإنشاء مدونة بسيطة
- استخدام عمليات CRUD لإدارة المدونة
- تطبيق المدونة الكامل
- إضافة بعض الميزات المتقدمة للمدونة
تثبيت الأدوات اللازمة
توجد بعض الأدوات التي يجب تثبيتها على جهازك قبل البدء، حيث تحتاج مبدئيًا لغة برمجة (بايثون)، وقاعدة بيانات (SQLite)، وخادم (سنستخدم خادم التطوير المُدمَج مع جانغو) لتشغيل التطبيق بنجاح. تذكّر أن هذه الأدوات مُخصَّصة لبيئة التطوير Dev Environment المخصصة لإنشاء واختبار التطبيق فقط، لذا لا يجب استخدام هذه الأدوات في بيئة الإنتاج Production Environment.
تحتاج أيضًا إلى بيئة تطوير متكاملة IDE مثل بيئة باي تشارم PyCharm أو محرّر شيفرات برمجية على الأقل، حيث سنستخدم في هذا المقال المحرّر VS Code لأنه برنامج مجاني.
اتبّع الآن الخطوات التالية للحصول على هذه الأدوات:
إنشاء مشروع جانغو جديد
حان الوقت لبدء كتابة الشيفرة البرمجية بعد تثبيت الأدوات السابقة، لذا أنشئ أولًا مجلد عمل جديد باستخدام الأمر التالي لتنظيم كل شيء:
mkdir django-demo
ثم انتقل إلى هذا المجلد باستخدام الأمر التالي:
cd django-demo
أنشئ بعد ذلك بيئة افتراضية جديدة للغة بايثون ضمن مجلد العمل باستخدام الأمر التالي، حيث ستكون هذه البيئة الافتراضية معزولة عن بيئة بايثون في نظامك ومشاريع بايثون الأخرى التي قد تكون على جهازك.
python -m venv env
إذا استخدمتَ نظام لينكس Linux أو ماك macOS، فقد تضطر إلى تشغيل أمر python3
بدلًا من python
، ولكننا سنستخدم python
للتبسيط. سيعمل الأمر السابق على إنشاء المجلد env
الذي يحتوي على البيئة الافتراضية التي أنشأتها، ويمكنك تنشيط هذه البيئة الافتراضية باستخدام الأمر التالي:
source env/bin/activate
وإذا استخدمتَ نظام ويندوز Windows، فاستخدم الأمر التالي بدلًا من ذلك:
env/Scripts/activate
إذا نشطت البيئة الافتراضية بنجاح، فسيكون موجّه سطر الأوامر الخاص بك كما يلي:
(env) eric@djangoDemo:~/django-demo$
ملاحظة: يعني (env)
هنا أنك تعمل حاليًا في بيئة افتراضية اسمها env
.
حان الوقت الآن لتهيئة مشروع جانغو جديد، حيث تحتاج إلى تثبيت حزمة Django
من خلال تشغيل الأمر التالي:
python -m pip install Django
ثم يمكنك استخدام أمر django-admin
لإنشاء مشروع جانغو جديد كما يلي:
django-admin startproject djangoBlog
وسينشَأ المجلد الجديد djangoBlog
التالي:
يُفضَّل إعادة هيكلة المشروع بعض الشيء بحيث نبدأ من المجلد الجذر للمشروع كما يلي، ولكن لا حاجة لذلك إن لم ترغب في ذلك.
إنشاء تطبيق المدونة
لا يزال المشروع فارغًا حاليًا، ولاحظ أن بنية هذا المشروع بسيطة مقارنةً ببنية مشروع لارافيل Laravel، وسنناقش كل ملف في مجلد المشروع بالتفصيل لاحقًا.
يتيح جانغو إنشاء تطبيقات متعددة في مشروع واحد، فمثلًا يمكن أن يكون هناك تطبيق blog
وتطبيق gallery
وتطبيق forum
ضمن مشروع واحد. يمكن أن تتشارك هذه التطبيقات في نفس الملفات الثابتة (ملفات CSS وجافاسكربت JavaScript) والصور ومقاطع الفيديو أو يمكن أن تكون مستقلة تمامًا عن بعضها البعض، إذ يعتمد ذلك على احتياجاتك الخاصة.
سننشئ في هذا المقال تطبيق مدونة blog
فقط، لذا نفّذ الأمر التالي في الطرفية:
python manage.py startapp blog
يجب أن ترى مجلد blog
جديد ضمن مجلد جذر المشروع، ويمكنك سرد محتوى المجلد باستخدام الأمر التالي:
ls
وإذا أردتَ تضمين الملفات المخفية أيضًا في النتيجة، فاستخدم الأمر التالي:
ls -a
وإذا أردتَ رؤية بنية الملفات فاستخدم الأمر التالي:
tree
ولكن قد تحتاج إلى تثبيت برنامج tree
ليعمل الأمر السابق بنجاح اعتمادًا على نظام تشغيلك. سنستخدم الأمر السابق لعرض بنية الملفات، حيث يجب أن يكون لمشروعك البنية التالية حاليًا:
. ├── blog │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ ├── models.py │ ├── tests.py │ └── views.py ├── djangoBlog │ ├── asgi.py │ ├── __init__.py │ ├── __pycache__ │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── env │ ├── bin │ ├── include │ ├── lib │ ├── lib64 -> lib │ └── pyvenv.cfg └── manage.py
يجب بعد ذلك تسجيل تطبيق blog
الجديد في جانغو، لذا انتقل إلى الملف settings.py
وابحث عن القائمة INSTALLED_APPS
:
INSTALLED_APPS = [ 'blog', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
بدء تشغيل الخادم
يمكنك الآن بدء تشغيل خادم التطوير لاختبار نجاح عمل كل شيء، لذا افتح الطرفية وشغّل الأمر التالي:
python manage.py runserver
وسيظهر الخرج التالي في واجهة سطر الأوامر:
Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. October 19, 2022 - 01:39:33 Django version 4.1.2, using settings 'djangoBlog.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
افتح المتصفح وانتقل إلى العنوان http://127.0.0.1:8000/
، وستظهر الصفحة التالية:
بنية التطبيق
لنتحدث عن البنية التالية لتطبيق جانغو الجديد وما يفعله كل ملف قبل أن نبدأ في كتابة الشيفرة البرمجية:
. ├── blog │ ├── admin.py │ ├── apps.py │ ├── __init__.py │ ├── migrations │ ├── models.py │ ├── tests.py │ └── views.py ├── djangoBlog │ ├── asgi.py │ ├── __init__.py │ ├── __pycache__ │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── env │ ├── bin │ ├── include │ ├── lib │ ├── lib64 -> lib │ └── pyvenv.cfg └── manage.py
المجلد الجذر
يحتوي المجلد الجذر على الملفات والمجلدات التالية:
-
manage.py
: يمثل أداة سطر الأوامر التي تتيح لك التفاعل مع مشروع جانغو بطرق مختلفة. -
djangoBlog
: مجلد المشروع الرئيسي الذي يحتوي على ملف الإعدادات ونقطة الدخول إلى المشروع. -
blog
: يمثل تطبيق المدونةblog
.
مجلد المشروع
يحتوي هذا المجلد على الملفات التالية:
-
djangoBlog/__init__.py
: ملف فارغ يخبر بايثون بأن هذا المجلد يجب عَدّه حزمة بايثون. -
djangoBlog/settings.py
: ملف الإعدادات أو الضبط Configuration لمشروع جانغو. -
djangoBlog/urls.py
: يحتوي على التصريحات عن عناوين URL لمشروع جانغو، ويمثل جدول محتويات تطبيق جانغو الخاص بك، حيث سنتحدث عنه أكثر لاحقًا. -
djangoBlog/asgi.py
: يُعَد نقطة الدخول لخوادم الويب المتوافقة مع واجهة ASGI لتخديم مشروعك. -
djangoBlog/wsgi.py
: نقطة الدخول لخوادم الويب المتوافقة مع واجهة WSGI لتخديم مشروعك.
مجلد التطبيق
يحتوي هذا المجلد على المجلدات والملفات التالية:
-
blog/migrations
: يحتوي هذا المجلد على جميع ملفات التهجير Migration لتطبيق المدونة، حيث ينشئ جانغو هذه الملفات تلقائيًا بناءً على نماذجك Models على عكس إطار عمل لارافيل. -
blog/admin.py
: يأتي جانغو أيضًا مع لوحة مُدمَجة لإدارة الموقع، حيث يحتوي هذا الملف على جميع عمليات الضبط الخاصة بهذه اللوحة. -
blog/models.py
: تصف النماذج Models بنية وعلاقة قاعدة البيانات، وتُنشَأ ملفات التهجير بناءً على هذا الملف. -
blog/views.py
: يكافئ المتحكمات Controllers في لارافيل، ويحتوي على المنطق البرمجي الأساسي لهذا التطبيق.
ضبط Configuring مشروع جانغو
توجد بعض التغييرات التي يجب إجراؤها على الملف settings.py
قبل البدء بالشروع كما سنوضح فيما يلي.
المضيفون المسموح بهم
تُعد القائمة ALLOWED_HOSTS
قائمة بالنطاقات Domains التي يُسمَح لموقع جانغو بتخديمها، وهي إجراء أمني لمنع هجمات ترويسات مضيف HTTP أو HTTP Host Header Attacks، والتي يمكن حدوثها حتى عند إجراء العديد من عمليات ضبط خادم الويب الآمنة ظاهريًا.
لاحظ أنه ما زال بإمكاننا الوصول إلى موقعنا باستخدام المضيف 127.0.0.1
حتى وإن كانت القائمة ALLOWED_HOSTS
فارغة حاليًا، والسبب هو التحقق من صحة المضيف مقابل ['.localhost', '127.0.0.1', '[::1]']
عندما تكون قيمة DEBUG
هي True
وتكون القائمة ALLOWED_HOSTS
فارغة.
قاعدة البيانات
DATABASES
هو قاموس يحتوي على إعدادات قاعدة البيانات التي يحتاج موقعنا إلى استخدامها، حيث يستخدم جانغو قاعدة بيانات SQLite افتراضيًا، وهي قاعدة بيانات خفيفة الوزن وتتكون من ملف واحد فقط. يجب أن تكون قاعدة بيانات SQLite كافيةً لمشروعنا التجريبي الصغير، لكنها لن تناسب المواقع الكبيرة، لذا إذا أردتَ استخدام قواعد بيانات أخرى، فإليك المثال التالي:
DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": "<database_name>", "USER": "<database_user_name>", "PASSWORD": "<database_user_password>", "HOST": "127.0.0.1", "PORT": "5432", } }
ملاحظة: يوصي جانغو باستخدام قاعدة بيانات PostgreSQL في بيئة الإنتاج. توجد العديد من البرامج التعليمية التي تعلمك كيفية استخدام جانغو مع قاعدة بيانات MongoDB، ولكنها تُعَد فكرة سيئة، إذ قد تكون قاعدة بيانات MongoDB حلًا رائعًا، ولكنها لا تعمل بطريقة جيدة مع إطار عمل جانغو.
الملفات الساكنة Static Files وملفات الوسائط Media Files
يجب أن نهتم أيضًا بالملفات الساكنة وملفات الوسائط، فالملفات الساكنة هي ملفات CSS وملفات جافاسكربت، وملفات الوسائط هي الصور ومقاطع الفيديو والأمور الأخرى التي قد يرفعها المستخدم.
الملفات الساكنة Static Files
يجب أولًا تحديد مكان تخزين هذه الملفات، حيث سننشئ المجلد static
ضمن تطبيق المدونة لموقع جانغو الخاص بنا، ويُعَد هذا المجلد هو المكان الذي نخزّن فيه الملفات الساكنة لتطبيق blog
أثناء التطوير.
blog ├── admin.py ├── apps.py ├── __init__.py ├── migrations ├── models.py ├── static ├── tests.py └── views.py
تختلف الأمور بعض الشيء في بيئة الإنتاج، إذ يجب أن ننشئ مجلدًا مختلفًا ضمن المجلد الجذر للمشروع، ولنسمّيه بالاسم staticfiles
.
. ├── blog ├── db.sqlite3 ├── djangoBlog ├── env ├── manage.py └── staticfiles
ثم يجب تحديد هذا المجلد في الملف settings.py
كما يلي:
STATIC_ROOT = "staticfiles/"
نخبر بعد ذلك جانغو بعنوان URL الذي يجب استخدامه عند الوصول إلى هذه الملفات في المتصفح. ليس من الضروري أن يكون هذا العنوان هو /static
، ولكن تأكد من أنه لا يتداخل مع عمليات ضبط عناوين URL الخاصة بنا والتي سنتحدث عنها لاحقًا.
STATIC_URL = "static/"
ملفات الوسائط Media Files
نضبط ملفات الوسائط باستخدام الطريقة نفسها، حيث يمكنك إنشاء المجلد mediafiles
في المجلد الجذر للمشروع كما يلي:
. ├── blog ├── db.sqlite3 ├── djangoBlog ├── env ├── manage.py ├── mediafiles └── staticfiles
ثم نحدّد الموقع وعنوان URL في الملف settings.py
كما يلي:
# ملفات الوسائط MEDIA_ROOT = "mediafiles/" MEDIA_URL = "media/"
موجه إرسال Dispatcher عناوين URL في جانغو
يحتوي مجال تطوير الويب على بنية نموذج-عرض-متحكم Model-View-Controller (أو MVC اختصارًا)، حيث يكون النموذج Model في هذه البنية مسؤولًا عن التفاعل مع قاعدة بياناتنا، ويجب أن يقابل كلُّ نموذج جدولَ قاعدة بيانات واحد. العرض View هو جزء الواجهة الأمامية Frontend من التطبيق، وهو ما يمكن للمستخدمين رؤيته، والمتحكم Controller هو المنطق البرمجي للواجهة الخلفية للتطبيق مثل استرداد البيانات من قاعدة البيانات عبر النماذج ووضعها في العرض المقابل وإعادة القالب المعروض إلى المستخدم في النهاية.
جانغو هو إطار عمل ويب مُصمَّم بناءً على بنية MVC مع مصطلحات مختلفة، فبنية جانغو هي بنية نموذج-قالب-عرض Model-Template-View (أو MTV اختصارًا)، فالقالب Template هو الواجهة الأمامية، والعرض هو المنطق البرمجي للواجهة الخلفية. سنركّز في هذا المقال على فهم هذه الطبقات، ولكن يجب أولًا البدء بنقطة الدخول لكل تطبيق ويب، والتي هي موجّه إرسال Dispatcher عناوين URL، حيث يقرأ هذا الموجّه عنوان URL ويوجّه المستخدم إلى الصفحة الصحيحة عندما يكتب المستخدم عنوان URL ويضغط على مفتاح Enter
.
عمليات ضبط عناوين URL الأساسية
يُخزَّن ضبط عناوين URL في الملف example/urls.py
كما يلي:
djangoBlog ├── asgi.py ├── __init__.py ├── __pycache__ ├── settings.py ├── urls.py └── wsgi.py
يوضّح المثال التالي ما يجب أن يبدو عليه موجّه إرسال عناوين URL:
from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
يقرأ موجّه الإرسال المعلومات من عنوان URL ويعيد عرضًا، ولكن لا تخلط بين هذا العرض وعرض إطار عمل لارافيل، فالعرض في جانغو يمثّل متحكّمًا في لارافيل. إذا تبع النطاقُ admin/
في هذا المثال، فسيوجّه موجّه الإرسال المستخدم إلى صفحة المدير Admin.
تمرير المعاملات باستخدام موجه إرسال عناوين URL في جانغو
يكون من الضروري في بعض الأحيان أخذ مقاطع من عنوان URL وتمريرها إلى العرض بوصفها معاملات إضافية، فمثلًا إذا أردتَ عرض صفحة التدوينة، فستحتاج إلى تمرير المعاملَين id
أو slug
الخاصين بالتدوينة إلى العرض حتى تتمكّن من استخدام هذه المعلومات الإضافية للعثور على التدوينة التي تبحث عنها. إليك فيما يلي الطريقة التي يمكننا تمرير المعاملات باستخدامها:
from django.urls import path from blog import views urlpatterns = [ path('post/<int:id>', views.post), ]
ستلتقط الأقواس الزاويّة جزءًا من عنوان URL كمعامل، حيث يُسمَّى int
على الجانب الأيسر بمحوِّل المسار Path Converter الذي يلتقط معاملًا من النوع الصحيح، ويمكن مطابقة أيّ سلسلة نصية باستثناء المحرف /
عند عدم تضمين المحوّل. لاحظ وجود اسم المعامل على الجانب الأيمن، وهو ما سنحتاج إلى استخدامه في العرض.
تتوفّر محوّلات المسارات التالية افتراضيًا:
-
str
: يطابق أيّ سلسلة نصية غير فارغة باستثناء فاصل المسار'/'
افتراضيًا عند عدم تضمين محوّلٍ في التعبير. -
int
: يطابق الصفر أو أيّ عدد صحيح موجب، ويعيد قيمة من النوعint
. -
slug
: يطابق أيّ سلسلة نصية للاسم المختصر Slug، والذي يتكون من حروف أو أرقام ASCII، بالإضافة إلى محارف الشرطة والشرطة السفلية مثلbuilding-your-1st-django-site
. -
uuid
: يطابق معرّف UUID المنسَّق، حيث يجب تضمين شرطات، ويجب أن تكون الحروف صغيرة لمنع ربط عناوين URL متعددة مع الصفحة نفسها مثل المعرّف075194d3-6885-417e-a8a8-6c931e272f00
، ويعيد نسخةً منUUID
. -
path
: يطابق أي سلسلة نصية غير فارغة مع فاصل المسار'/'
، مما يتيح لك المطابقة مع مسار URL كامل بدلًا من المطابقة مع مقطعٍ من مسار URL كما هو الحال مع المحوِّلstr
.
استخدام التعابير النمطية Regular Expressions لمطابقة أنماط عناوين URL
قد يكون النمط Pattern الذي تريد مطابقته أكثر تعقيدًا في بعض الحالات، وبالتالي يمكنك استخدام التعابير النمطية Regular Expressions لمطابقة أنماط عناوين URL.
يجب استخدام التابع re_path()
بدلًا من التابع path()
لاستخدام التعابير النمطية:
from django.urls import path, re_path from . import views urlpatterns = [ path('articles/2003/', views.special_case_2003), re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive), re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail), ]
استيراد عمليات ضبط عناوين URL الأخرى
لنفترض أن لديك مشروع جانغو يحتوي على تطبيقات متعددة مختلفة، حيث إذا وضعت جميع عمليات ضبط عناوين URL في ملف واحد، فسيكون الأمر فوضويًا جدًا، ولكن يمكنك فصل عمليات ضبط عناوين URL ونقلها إلى تطبيقات مختلفة، فمثلًا يمكننا في مشروعنا إنشاء ملف urls.py
جديد ضمن تطبيق blog
كما يلي:
from django.urls import path, include urlpatterns = [ path('blog/', include('blog.urls')) ]
وهذا يعني أنه إذا احتوى عنوان URL على النمط http://www.mydomain.com/blog/xxxx
، فسينتقل جانغو إلى الملف blog/urls.py
ويطابق باقي عنوان URL.
لنعرّف الآن أنماط عناوين URL لتطبيق blog
باستخدام الطريقة نفسها كما يلي:
from django.urls import path from blog import views urlpatterns = [ path('post/<int:id>', views.post), ]
سيتطابق هذا النمط مع نمط عنوان URL الذي هو http://www.mydomain.com/blog/post/123
.
تسمية أنماط عناوين URL
يمكنك تسمية نمط عنوان URL من خلال إعطائه معاملًا ثالثًا كما يلي:
urlpatterns = [ path('articles/<int:year>/', views.year_archive, name='news-year-archive'), ]
يؤدي ذلك إلى القدرة على عكس عناوين URL المطلقة من القالب، حيث سنتحدث عن ذلك لاحقًا عندما نصل إلى طبقة القوالب.
تعرّفنا على أساسيات موجّه إرسال عناوين URL، ولكن لا زال هناك شيء لم نتطرق لشرحه وهو كيفية التمييز بين التوابع المختلفة لطلبات HTTP، حيث لا يمكنك في جانغو مطابقة توابع HTTP المختلفة ضمن موجه إرسال عناوين URL، إذ تتطابق جميع التوابع مع نمط عنوان URL نفسه، وبالتالي يجب استخدام التحكم في التدفق لكتابة شيفرات برمجية مختلفة لهذه التوابع في دوال العرض، حيث سنناقش ذلك بالتفصيل في المقالات اللاحقة من هذه السلسلة.
ترجمة -وبتصرّف- للمقال Django for Beginners #1 - Getting Started لصاحبه Eric Hu.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.