بناء منطقة أعضاء متكاملة على موقعي باستخدام بايثون وجانغو: دروس مستفادة وتحديات تقنية
مقدمة: رحلة بناء منطقة الأعضاء باستخدام Python و Django
في عالم الويب المتسارع، تتزايد الحاجة إلى توفير تجارب مخصصة للمستخدمين، ومن أبرزها إنشاء مناطق للأعضاء. قررتُ مؤخرًا ترقية موقعي الشخصي لإتاحة الفرصة للزوار لشراء دوراتي التدريبية والوصول إليها عبر بوابة جديدة. كان هدفي واضحًا: توفير منصة للمستخدمين للتسجيل، استعراض الدورات المتاحة، وشرائها. وبمجرد شراء الدورة، سيتمكن المستخدم من الوصول إلى محتواها بالكامل مدى الحياة.
قد تبدو هذه الفكرة بسيطة نظريًا، لكن بناء مواقع العضوية، خاصة بدون الاعتماد على منصات التجارة الإلكترونية الجاهزة مثل Shopify، ينطوي على تعقيدات غير متوقعة. في هذا المقال، سأشارككم القرارات التقنية التي اتخذتها والمكدس التقني الذي استخدمته لبناء هذا الموقع الجديد، متناولًا المحاور التالية:
- كيف بدأتُ المشروع؟
- إعداد مشروع
Django. - كيفية إعداد نماذج
Django(Django Models). - دمج بوابات الدفع
Stripe. - نشر الموقع الجديد على خادم
AWS EC2. - كيفية استنساخ تنسيقات
CSSمن صفحة موجودة.
كيف بدأتُ المشروع؟ التخطيط واختيار المكدس التقني
تنظيم الموقع عبر النطاقات الفرعية (Subdomains)
عند إضافة قسم جديد إلى موقعك بمجموعة ميزات مختلفة تمامًا، من المنطقي تنظيم هذا القسم كنطاق فرعي (subdomain) من موقعك الأصلي. النطاق الفرعي هو بالضبط ما يوحي به اسمه؛ إنه جزء من نطاق رئيسي آخر. تظهر النطاقات الفرعية كقسم جديد في عنوان URL الخاص بنطاقك قبل عنوان URL للنطاق الرئيسي. على سبيل المثال:
- نطاقي الرئيسي:
https://nickmccullum.com - نطاق الدورات الفرعي الجديد:
https://courses.nickmccullum.com
الميزة الرئيسية للنطاقات الفرعية أنها مجانية! بالإضافة إلى ذلك، فإن النطاق الفرعي المرتبط بموقع مصنف جيدًا بالفعل يتم فهرسته بسرعة ويستفيد من نجاح النطاق الأم.
اختيار الاستضافة السحابية
كنت أعلم أنني سأحتاج إلى خادم لاستضافة موقعي الجديد، وسأحتاج أيضًا إلى ربط هذا الخادم بعنوان IP مرن (elastic IP address). عنوان IP المرن هو عنوان IP ثابت لا يتغير أبدًا، مما يعني أنه يمكن الوصول إليه من قبل الجمهور على مدار الساعة طوال أيام الأسبوع.
أسرع طريقة لتشغيل خادم في الوقت الحاضر هي استضافته في السحابة. هناك العديد من الخيارات للحوسبة السحابية، بما في ذلك AWS من Amazon، و DigitalOcean's Droplets، أو Azure's Containers. من حيث التسعير، فإن الخيارات المتاحة متساوية إلى حد ما عبر جميع المنصات، لذلك لم يؤثر ذلك كثيرًا في قراري. كانت لدي خبرة سابقة مع AWS (Amazon Web Services)، وهي خدمة سحابية لاستضافة البنية التحتية، لذلك اخترت بشكل طبيعي استضافة خادمي هناك. لتحديد أكثر، أنا أستضيف الموقع على EC2 instance، وسنتحدث عن ذلك لاحقًا.
اختيار المكدس التقني (Tech Stack)
بمجرد أن عرفتُ أين أرغب في استضافة موقعي الجديد، كان السؤال التالي: ما هو المكدس التقني الذي سأستخدمه؟ عند التفكير في التكنولوجيا التي ستستخدمها لبناء موقعك، من المهم مراعاة هذه الموضوعات الرئيسية:
- ما هي التقنيات التي تتقنها جيدًا؟
- اختيار تقنيات الواجهة الأمامية (
frontend) والواجهة الخلفية (backend) التي تتكامل بشكل جيد. - أداء الموقع.
يجب عليك الإجابة على هذه الأسئلة ومحاولة اختيار مكدس تقني يناسب احتياجاتك وقدراتك. بالنسبة لي، أنا الأكثر كفاءة في Python، لذلك كان Django 3.0 خيارًا طبيعيًا! لقد عملت على تطبيق Django من قبل (Passiv)، لذلك كنت على دراية واسعة بالبنية التحتية. ومع ذلك، لم أقم ببناء مشروع Django من الصفر من قبل، ولهذا السبب، كان عليّ بعض القراءة والبحث.
Django مقابل PHP: مقارنة الأداء والأمان
بينما كنت أتعلم المزيد عن هذا الإطار الشهير، كنت أقارنه باستمرار بلغة PHP، أداة البرمجة الويب الشائعة. لقد عملت على العديد من مواقع WordPress في الماضي، و WordPress مبني على PHP، لذلك كانت هذه مقارنة طبيعية (بالنسبة لي على الأقل). وفقًا لوثائقهم ومنشورات مختلفة على Stack Overflow، إليك الاختلافات الرئيسية بين إطار عمل Django وأطر عمل PHP الرئيسية:
- يركز
Djangoبشكل أكبر على الأمان افتراضيًا ويوفر ممارسات أمان مدمجة لمساعدة المبرمجين على توفير الوقت أثناء التطوير. - يركز
Djangoعلى السرعة. يُعرف بأنه إطار عمل يساعد المطورين على إطلاق مواقعهم بأسرع وقت ممكن. - يتمتع
Djangoبأداء أقل هامشيًا مقارنة بمعظم أطر عملPHP.
أود أن أتطرق إلى النقطة الأخيرة. Python هي لغة مفسرة (interpreted language) وترتبط عادةً بأداء أقل من لغات البرمجة الأخرى. عندما يسمع مبرمج جديد شيئًا كهذا، قد يعتقد أن Python أسوأ بكثير من خيارات اللغات الأخرى بسبب أهمية الأداء في الحوسبة. على الرغم من أن Python لديها معايير أداء أقل مقارنة بلغات أخرى، إلا أن هذا تصريح غامض للغاية. في الواقع، الفرق بين Django و Laravel (إطار عمل شائع يعتمد على PHP) صغير جدًا لدرجة أنه يعتبر مهملًا. لكي يكون فرق الأداء هذا مهمًا بالنسبة لك، ستحتاج إلى كتابة تطبيق يعتمد بشكل كبير على الأداء ويخدم ملايين المستخدمين.
لقد شجعني معرفة أن العديد من أكبر تطبيقات الويب في العالم مبنية على Django. بعبارة أخرى، إذا كان Django جيدًا بما يكفي لـ Instagram، فإنه بالتأكيد كان ذا أداء كافٍ لموقعي. في النهاية، قررت بناء موقع الدورات التدريبية الخاص بي باستخدام Django بشكل أساسي لأن لدي خبرة في Python. كان تعلم إطار عمل ويب جديد مكافأة إضافية لطيفة.
اختيار قاعدة البيانات: قوة SQLite3
بعد ذلك، كنت أعلم أنني سأحتاج إلى قاعدة بيانات لهذا الموقع. نظرًا لخبرتي مع MySQL و PostgreSQL، كنت سأعود في الأصل إلى استخدامهما هنا. ومع ذلك، يأتي Django افتراضيًا مع خدمة قاعدة بيانات SQLite3 التي تتطلب الحد الأدنى من الإعداد. لم أستخدم SQLite من قبل، لذلك أجريت المزيد من البحث.
بناءً على احتياجات الأداء وتخزين البيانات، ستكون قاعدة بيانات SQLite3 الافتراضية المرفقة مع Django أكثر من كافية لموقعي. لقد صدمت عندما وجدت أن إصدارًا أخف من خدمة قاعدة البيانات يمكن أن يكون قويًا جدًا! لأي شخص غير مطلع على هذه التكنولوجيا (مثلي)، SQLite3 هي قاعدة بيانات علائقية (relational database) ذات أداء رائع للمواقع ذات مستويات حركة المرور المنخفضة إلى المتوسطة (حوالي 100 ألف زيارة في اليوم). يمكن تشغيل SQLite3 على نفس الخادم الذي يستضيف الموقع دون التأثير على الأداء. هذا يعني أنني لم أكن بحاجة إلى تشغيل Amazon RDS instance منفصل، مما يوفر بعض المال في مرحلة النشر.
إعداد مشروع Django: البدء السريع
لماذا Django؟
Django هو إطار عمل ويب عالي المستوى لـ Python، وهدفه الرئيسي هو السماح بالتطوير السريع وتوفير الأمان افتراضيًا. إنه يعتني بالعديد من متاعب تطوير الويب، مما يقلل من ممارسات البرمجة المتكررة. أحد أفضل أجزاء استخدام Django هو أنه مجاني تمامًا. تم تصميم Django لمساعدة المطورين على إطلاق مواقعهم بسرعة (وهو أحد الأسباب الرئيسية التي دفعتني لاختياره لهذا المشروع).
نظام القوالب (Templating System) في Django
إحدى الميزات المفضلة لدي في هذا الإطار (كما هو الحال في معظم الأطر الأخرى) هو نظام القوالب الأمامية (frontend templating system). تتيح لك قوالب Django (Django Templates) كتابة تعليمات برمجية ديناميكية تقوم بعد ذلك بإنشاء HTML و CSS المطلوبين. يمنحك هذا القدرة على استخدام هياكل مثل الحلقات (loops) والجمل الشرطية (if statements) لإنشاء تعليمات HTML برمجية ديناميكية (مما يعني أنها تُعرض بشكل مختلف لكل مستخدم) والتي يمكن بعد ذلك تقديمها كملف ثابت. على سبيل المثال:
# course_titles_template.html
{% for course in courses_list %}
<h1> {{ course.course_title }} </h1>
{% endfor %}
سينشئ هذا الكود عنوانًا لكل متغير دورة موجود في كائن courses_list. سيقوم هذا الكود بعرض ملف HTML يحتوي على وسم <h1> يتضمن عنوان كل دورة، مثل هذا:
<h1> Python Fundamentals </h1>
<h1> Advanced Python for Finance and Data Science </h1>
<h1> How to Run Python Scripts </h1>
<h1> How to Make A Python Class </h1>
يوفر لك نظام القوالب الكثير من العمل اليدوي. يتيح عرض HTML ديناميكيًا تجنب عناء تحديث الكود في كل مرة تضيف فيها كائنًا جديدًا. يسمح نظام القوالب هذا أيضًا لتطبيق الويب بالتحديث بمرور الوقت مع إضافة المزيد من المحتوى. لذلك في هذه الحالة، إذا أضفت دورة جديدة إلى قاعدة بياناتي، فلن يحتاج هذا القالب إلى التغيير. سيعرض ببساطة عنوان الدورة الجديدة في وسم عنوان جديد.
تثبيت Django وبدء مشروع
يجعل Django البدء في المشروع أمرًا سهلاً للغاية. بمجرد تثبيت Django، يمكنك استخدام أداة django-admin لبدء مشروع وحتى إعداد تطبيقاتك. لحظة، تطبيقات؟ مشاريع؟ ما الفرق؟
- التطبيق (
App): هو تطبيق ويب يؤدي بعض الوظائف. يمكن أن يكون مدونة، أو نظام تسجيل دخول، أو حتى خادم ملفات. - المشروع (
Project): هو مجموعة من التطبيقات والتكوينات التي تشكل معًا موقع ويب.
تثبيت Django:
أبسط طريقة للتثبيت هي باستخدام pip، مدير حزم Python:
python -m pip install Django
للحصول على دليل تثبيت كامل، راجع وثائق Django الرسمية.
بدء مشروع:
بمجرد تثبيت Django، ستتمكن من الوصول إلى أداة django-admin التي تساعد المطورين في إعداد المشاريع والتطبيقات، وتوفر أيضًا أدوات أخرى مفيدة. سيؤدي تشغيل الأمر django-admin startproject myproject إلى إنشاء مجلد جديد في الدليل الحالي حيث سيعيش مشروعك. سيقوم أيضًا بإنشاء العديد من الملفات الضرورية التي ستحتاجها للبدء. إليك ما سيبدو عليه دليلك بعد تشغيل هذا الأمر:
myproject/
manage.py
myproject/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
داخل مجلد myproject الخارجي، ستجد ملف manage.py، وهو مفيد للغاية ويوفر العديد من الأدوات المساعدة. سيكون هناك مجلد آخر باسم myproject وهو المكان الذي ستحدد فيه تكوينات مشروعك. الدليل الجذر الخارجي myproject/ هو حاوية لمشروعك، واسمه لا يهم في الواقع، وإذا وجدت هذا مربكًا يمكنك إعادة تسميته بأي شيء تريده. الدليل الداخلي myproject/ هو حزمة Python الفعلية لمشروعك. اسمه هو اسم حزمة Python التي ستحتاج إلى استخدامها لاستيراد أي شيء بداخله.
الملفات المهمة التي يجب ملاحظتها هنا هي myproject/settings.py، حيث يتم تكوين إعدادات Django والتطبيق، و myproject/urls.py. يُستخدم ملف urls.py لإنشاء عناوين URL داخل موقع الويب الخاص بك وتوجيهها إلى موقع لخدمة الطلب. توضح هذه الصورة بشكل ممتاز كيفية تعامل Django مع الطلبات:
الشكر لـ Ryan Nevius على هذا التصور الرائع. يحدد ملف myproject/urls.py حل URL للموقع بأكمله. سيحتوي كل تطبيق تضيفه إلى موقع الويب الخاص بك على ملف urls.py خاص به يحدد حل URL داخل هذا التطبيق المحدد.
الآن بعد أن أصبح لديك فهم لبعض استخدامات هذه الملفات، دعنا نتعمق في بدء مشروع باستخدام أوامر السكريبت الخاص بالمدير. أحد الأوامر التي يجب ملاحظتها هو أمر startapp المستخدم لإنشاء تطبيق داخل مشروعك بنفس الطريقة التي أنشأت بها المشروع. سيؤدي python manage.py startapp myapp إلى إنشاء مجلد جديد وبعض الملفات الضرورية لإنشاء تطبيق جديد في مشروعك:
myapp/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
الفرق الرئيسي هنا هو وجود ملفي models.py و views.py، اللذين يستخدمان لتعريف قاعدة البيانات ووظائف الواجهة الأمامية للتطبيق، على التوالي. النماذج (Models) هي فئات (classes) تحدد جداول قاعدة البيانات الخاصة بك. سنناقش النماذج بمزيد من التفصيل لاحقًا في هذا الدليل. تتحكم العروض (Views) في بنية ووظائف الواجهة الأمامية للتطبيق، حيث تتلقى طلب ويب وتُرجع استجابة ويب.
ربما يكون أهم أمر يجب تذكره هو أمر runserver: python manage.py runserver. سيؤدي هذا إلى تشغيل مشروعك على جهازك المحلي (localhost) على المنفذ الافتراضي، 8000. هذا كل شيء! بثلاث خطوات بسيطة سترى صفحة ترحيب توضح أن التثبيت قد نجح.
يوجد برنامج تعليمي ممتاز ومفصل للغاية في وثائق Django يوفر شرحًا أعمق بكثير لبدء المشروع.
كيفية إعداد النماذج (Models) في Django
مفهوم ORM ونماذج Django
مثل العديد من أطر عمل الويب الأخرى، يمتلك Django تطبيقًا لمفهوم تعيين الكائنات العلائقية (Object-Relational Mapping - ORM). في Django، يسمى هذا التطبيق بالنماذج (models). النماذج موضوع مهم جدًا لفهمه عند تطوير مشروع في Django. في أبسط صورها، يمكن اعتبار النماذج كأغلفة لجداول قاعدة البيانات. بعبارة أخرى، يُستخدم نموذج Django لتحديد بياناتك. يحتوي على الحقول (fields) وسلوكيات البيانات التي تخزنها. يتوافق كل نموذج مع جدول واحد في قاعدة بياناتك، وتتوافق الحقول في نموذجك مع الحقول في قاعدة بياناتك.
عند كتابة النماذج، يمكنك الوصول إلى أنواع حقول مدمجة قوية تقوم بالكثير من العمل الشاق نيابة عنك. انسَ كتابة كود SQL يدويًا لإنشاء قاعدة بياناتك. يمكنك ببساطة كتابة فئة نموذج (model class) وتشغيل أوامر الترحيل (migration commands) للحصول على سكربت SQL وظيفي بالكامل محمل في قاعدة بياناتك.
نماذج المستخدم المدمجة والنماذج المخصصة
يقدم Django نموذج مستخدم (User Model) كجزء من نظام المصادقة المدمج الخاص به، والذي يسمح لك بتجاهل الجانب الخلفي لجميع عمليات تسجيل الدخول والتسجيل ومعالجة كلمات المرور. عند تصميم النماذج لموقعي الجديد، احتجت إلى النماذج الثلاثة التالية:
Profile: فئة غلاف حول نموذج المستخدم لإضافة معلومات غير متعلقة بالمصادقة (غالبًا ما تسمىProfile Model).Course: لتخزين جميع المعلومات حول كل دورة.Document: نموذج يخزن معلومات حول الملفات المنسوبة إلى كل دورة. أردتُ تحديدًا تحميل مستنداتMarkdown، حيث أن مدونتي العامة مبنية بالفعل بهذه الطريقة.
إليك مثال على نموذج Profile:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
enrolled_courses = models.ManyToManyField(Course)
نموذج Profile هو أداة مفيدة لتوسيع وظائف نموذج المستخدم الحالي لتخزين معلومات حول المستخدم، بخلاف بيانات المصادقة فقط. في حالتي، أنشأتُ نموذج ملف تعريف باسم Profile لتخزين الدورات التي سجل فيها المستخدم.
إليك نموذج Course الخاص بي:
class Course(models.Model):
course_title = models.CharField(max_length=200)
course_description = models.CharField(max_length=500)
course_price = models.DecimalField(max_digits=10, decimal_places=2)
نموذج Course الخاص بي مباشر إلى حد ما. احتجت فقط إلى تخزين 3 أجزاء من المعلومات حول كل دورة لأغراض لوجستية، بينما يتم التعامل مع المحتوى الفعلي للدورة بواسطة نموذج Document.
class Document(models.Model):
course = models.ForeignKey(Course, on_delete=models.PROTECT)
file = models.FileField(upload_to=markdown_upload_location, default='default.md')
هنا، استفدتُ من بعض وظائف Python المدمجة، حيث أمرر الدالة markdown_upload_location إلى مُنشئ FileField. تُستخدم هذه الدالة لتحديد مكان تخزين الملف الذي يتم تحميله على نظام الملفات. يسمح تمرير الدالة إلى المُنشئ بتشغيل الدالة في كل مرة يتم فيها تحميل ملف جديد بدلاً من تشغيلها مرة واحدة فقط ثم استخدام نفس النتيجة مرارًا وتكرارًا. بشكل أساسي، عندما يقوم مسؤول (أنا) بتحميل دورة جديدة إلى الموقع، يتم إنشاء مجلد جديد لتلك الدورة ويتم تخزين جميع ملفات markdown الخاصة بتلك الدورة هناك. تقوم سجلات نموذج Document بربط تلك الملفات بسجل الدورة في قاعدة البيانات.
أحد الأشياء التي استخلصتها من إعداد هذه النماذج هو مدى سهولة عملية تصميم قاعدة بياناتي. لقد ولت أيام MySQL Workbench ومخططات ERR، أو كتابة SQL سطرًا بسطر وتنفيذ تحديثات مؤلمة للمخططات.
دمج بوابات الدفع Stripe
لماذا Stripe؟
Stripe هي منصة تستخدمها العديد من مواقع الويب حول العالم لقبول المدفوعات من العملاء. إنها آمنة، وسهلة الاستخدام للعملاء، والأهم من ذلك، أنها سهلة الإعداد لنا كمطورين! التسعير عادل جدًا أيضًا مقارنة بمنافسيها، حيث يبلغ حاليًا 2.9% + 0.30 دولار كندي لكل معاملة. ينطبق هذا التسعير على المدفوعات لمرة واحدة وكذلك على اشتراكاتهم.
لاستخدام Stripe كمطور، يجب عليك إنشاء حساب والاطلاع على صفحات المطورين الخاصة بهم لمراجعة الخيارات. لديهم بوابات دفع جاهزة (prebuilt checkouts)، ومكتبات كاملة، وحزم تطوير برمجيات (SDKs) لبناء بوابة دفع مخصصة خاصة بك. يوفر Stripe أيضًا مكونات إضافية (plugins) موجودة مسبقًا لأطر عمل الويب (مثل WordPress، Drupal، إلخ).
استخدام أداة Stripe Checkout
قررتُ استخدام أداة Checkout الخاصة بهم، وهي صفحة دفع آمنة يستضيفها Stripe سمحت لي بتجنب بناء صفحة دفع بنفسي. هذا لا يوفر فقط وقت تطوير صفحة الواجهة الأمامية لجمع معلومات الدفع، ولكنه يوفر أيضًا عناء تأمين الدفع في الواجهة الخلفية. الأمان موضوع ضخم في الوقت الحاضر، والعملاء حذرون بشأن المكان الذي يقدمون فيه تفاصيل بطاقاتهم الائتمانية، لذلك بالنسبة لي، كان استخدام Stripe قرارًا بديهيًا. أنا لا أقوم بتخزين أي من تفاصيل المستخدمين. بدلاً من ذلك، يتم إرسالها مباشرة إلى Stripe حيث يمكن التعامل معها بأمان.
ببضعة أسطر من الكود، تمكنتُ من استيراد وحدة JavaScript الجاهزة للدفع من Stripe. إليك وسم السكريبت:
<script
src="https://checkout.stripe.com/checkout.js"
class="stripe-button"
data-key="{{ key }}"
data-description="Payment: {{ course.course_title }}"
data-amount="{% multiply course.course_price 100 %}"
data-locale="auto"
>
</script>
هنا، تم تعيين data-key إلى مفتاح Stripe العام (public key)، على غرار أي مفتاح API للمطور. الوصف (description) هو ما سيظهر في لوحة تحكم Stripe الخاصة بك للمدفوعات المستلمة، والمبلغ (amount) هو عدد السنتات للمشتريات. هذا التضمين البسيط يستورد صفحة الدفع هذه كنافذة منبثقة (modal) على موقع الويب:
بمجرد أن يملأ العميل معلومات الدفع، تحتاج فقط إلى تجميع معلومات الدفع في طلب وإرسالها إلى Stripe. بعد ذلك، يتمكن Stripe من معالجة المعلومات والموافقة على الدفع في غضون ثوانٍ.
# Send the charge to Stripe
charge = stripe.Charge.create(
amount=amount,
currency=currency,
description=f"Payment for course: {courseTitle}",
source=self.request.POST['stripeToken']
)
نشر الموقع الجديد على خادم AWS EC2
اختيار وتكوين الخادم
بمجرد الانتهاء من تطوير موقعي الجديد على جهازي المحلي (localhost)، احتجت إلى العثور على مكان لنشره. كانت لدي بعض الخبرة مع AWS وكان لدي حساب بالفعل، مما جعل القرار سهلاً. تتيح خدمة Amazon's Elastic Compute Cloud (EC2)، والتي يشار إليها عادةً باسم EC2، وفرة من التكوينات. لقد اخترت ببساطة الإعداد الأكثر وضوحًا. على وجه التحديد، ستكون آلة Ubuntu تعمل على خادم T2 Micro كافية لأداء هذا الموقع. كان إعداد الخادم هو الجزء الأسهل من عملية النشر، فقد قمت بإعداد خادم في أقل من 10 دقائق.
بعد ذلك، كان عليّ ربط عنوان IP مرن (elastic IP address) بالخادم وتحديث سجلات نظام أسماء النطاقات (DNS records) في Route53 (حيث يعيش نطاقي).
خدمة Django عبر Apache و WSGI
بعد إعداد الخادم، كان عليّ معرفة كيفية تقديم الموقع للزوار. كانت لدي بعض الخبرة في الماضي مع Apache، لذلك كان خيارًا طبيعيًا. اتضح أن Apache و Django يتكاملان بشكل جيد للغاية. يتم تقديم Django عبر واجهة بوابة خادم الويب (Web Server Gateway Interface - WSGI) الخاصة به، وهي واجهة CGI سريعة لـ Python، وهذا مشابه لـ PHP's FPM إذا كنت على دراية بذلك. ببساطة، WSGI هي طبقة بين Django وخادم الويب تعمل كواجهة لتقديم صفحات الويب.
كما تعلمون بالفعل، يتم تشغيل Python عادةً داخل بيئة افتراضية (virtualenv). ينشئ هذا بيئة افتراضية حيث يمكن أن تعيش تبعيات مشروع معين دون التدخل في إصدار Python الخاص بالنظام. إذا كنت ترغب في معرفة المزيد عن virtualenv، فراجع دليل المسافرين إلى Python. هذا مهم بشكل أساسي لتكوين إعدادات Apache.
لتقديم الملفات بشكل صحيح، تحتاج إلى إنشاء WSGI Daemon لمشروع Django الخاص بك على النحو التالي:
# /etc/apache2/sites-available/mysite.conf:
WSGIProcessGroup courses.nickmccullum.com
WSGIDaemonProcess course python-path=/home/ubuntu/django/courses-website python-home=/home/ubuntu/django/courses-website-venv
WSGIProcessGroup course
WSGIScriptAlias / /home/ubuntu/django/courses-website/courses-website/wsgi.py
<VirtualHost *:80>
ServerName courses.nickmccullum.com
</VirtualHost>
يخبر هذا التكوين Apache باستخدام WSGI daemon لتقديم الملفات بشكل صحيح من مشروع Django. بمجرد إعداد ذلك، احتجت إلى إعادة تشغيل Apache، والانتظار 24 ساعة لتحديث سجلات DNS، ثم – ها هو ذا:
تأمين الموقع باستخدام SSL و Let's Encrypt
خطوة أخيرة، كان عليّ تأمين موقعي باستخدام طبقة المقابس الآمنة (SSL - Secure Socket Layer). بعد كل شيء، أطلب من الأشخاص إجراء مدفوعات على موقعي، لذلك سيتوقع العملاء أن يكون الموقع مؤمنًا! أبسط طريقة لتمكين SSL على موقع، في رأيي، هي من خلال Let's Encrypt. يقدمون أداة تسمى Certbot مجانًا، والتي يمكن تمكينها على خادمك لتجديد شهادة الخادم تلقائيًا والحفاظ على تشغيل خادمك مع SSL على مدار الساعة طوال أيام الأسبوع على مدار العام. الأمر بسيط مثل الخطوات الثلاث التالية:
- تثبيت
Certbot:sudo apt-get install certbot python3-certbot-apacheملاحظة: سيبحث هذا السكريبت عن إعداد
ServerNameفي ملف تكوينApacheالخاص بك لإنشاء الشهادة، لذا تأكد من تعيينه قبل تشغيله. - الحصول على الشهادة وإخبار
Certbotبتحديث تكوينApacheتلقائيًا:sudo certbot --apache - اختبار التجديد التلقائي:
sudo certbot renew --dry-run
بمجرد تكوين SSL، يمكنك الاختبار للتأكد من تثبيت الشهادة بشكل صحيح عن طريق التحقق من هذا الموقع: https://www.ssllabs.com/ssltest/. بعد تأمين موقعي باستخدام SSL، فتحت قواعد أمان مثيل EC2 للسماح للموقع بأن يكون عامًا. مع تشغيل موقعي الجديد على مثيل EC2 الخاص بي، أصبحت الآن قادرًا على بيع دوراتي بأمان للعملاء الذين يرغبون في التعلم عن مواضيع مختلفة في تطوير البرمجيات.
الخلاصة التقنية
لقد كانت رحلة بناء منطقة الأعضاء هذه باستخدام Python و Django تجربة تعليمية غنية ومليئة بالتحديات. أثبت Django كفاءته كإطار عمل قوي وسريع، خاصة مع ميزاته المدمجة للأمان ونظام ORM الذي يبسط التعامل مع قواعد البيانات بشكل كبير. كان قرار استخدام SQLite3 كقاعدة بيانات افتراضية للمشاريع ذات الحجم المتوسط قرارًا صائبًا، حيث وفر التكاليف والتعقيد دون التضحية بالأداء المطلوب. كما أن دمج Stripe Checkout كان خطوة حاسمة لضمان تجربة دفع آمنة وسلسة، مما أزال عبء التعامل مع بيانات البطاقات الحساسة.
أما بالنسبة للنشر على AWS EC2، فقد أكد مرونة وقوة الحوسبة السحابية، بينما أظهر تكامل Apache و WSGI و Certbot مدى سهولة إعداد بيئة إنتاج آمنة وفعالة. الدرس الأهم الذي تعلمته هو القيمة المطلقة للوثائق الرسمية المكتوبة جيدًا؛ فهي بوصلة لا غنى عنها لأي مطور يواجه تحديات جديدة. هذا المشروع لم يوسع فقط مهاراتي في تطوير الويب، بل عزز أيضًا فهمي لأهمية التخطيط الدقيق واختيار الأدوات المناسبة لكل مرحلة من مراحل دورة حياة التطوير.