المسارات في Django


محمد طاهر الموسوي

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

django-4.png

من المؤكّد أنّك وأثناء تجوالك في مواقع الإنترنت قد شاهدت روابط كهذه:

“ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B”

هذا الشكل من الروابط غير مرغوب فيه على الإطلاق في Django، إذ يستخدم هذا الإطار مفهوم أنماط المسارات URL patterns لإظهارها بصورة مرتبة وواضحة وذات دلالة في نفس الوقت.
والمقصود بأنماط المسارات بكل بساطة هو أن تمتلك المسارات نسقًا معينًا، مثل:

/newsarchive/<year>/<month>/

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

مسارات تطبيق الاقتراعات

سيؤدي تطبيق الاقتراعات الذي نعمل على إنشائه المهام التالية:

  1. صفحة رئيسية index تعرض عددًا من الأسئلة المطروحة في الموقع.
  2. صفحة تفاصيل السؤال detail تعرض سؤالًا معيّنًا إلى جانب الأجوبة المتاحة لهذا السؤال للتصويت.
  3. صفحة نتائج results تعرض النتائج المتعلقة بسؤال معين.
  4. عملية التصويت، والتي يتم من خلالها التصويت على جواب معين مرتبط بسؤال معين.

وكما ذكرنا في الدروس السابقة فإنّ عملية إرسال الطلبات وتلقي الإجابة عليها هي مهمة العروض؛ لذا سننشئ أربعة عروض يختص كل منها بمهمة محددة من المهام الأربعة الخاصة بالتطبيق.
افتح ملف polls/views.py في محرر النصوص المفضل لديك، ثم أضف الشيفرة التالية بعد دالة index التي أضفناها إلى هذا الملف في الدرس الثاني.

def detail(request, question_id):
    return HttpResponse("هذا هو السؤال  %s." % question_id)

def results(request, question_id):
    response = "هذه نتائج السؤال %s."
    return HttpResponse(response % question_id)

def vote(request, question_id):
    return HttpResponse("أنت تصوت على السؤال %s." % question_id)

الدالة الأولى هي دالة detail وهي المسؤولة عن عرض تفاصيل السؤال الذي يرغب المستخدم التصويت عليه، أما الدالة الثانية results فمسؤولة عن عرض نتائج التصويت على سؤال معين يختاره المستخدم، أما الدالة الثالثة vote فتتحكم في عملية التصويت التي يقوم بها المستخدم.
ستؤدي هذه الدوال في الوقت الحاضر مهمّة واحدة بسيطة وهي عرض عبارة خاصّة بكل دالّة على المتصفح مع إضافة معرّف السؤال الذي سيختاره المستخدم، وذلك للتعرف على آلية عمل المسارات في Django، وسنعود إلى هذه العروض في الدروس القادمة وبشكل تفصيلي لإضافة الشيفرة التي ستعطي النتيجة الفعلية المطلوبة من كل دالة من هذه الدوال.
لعرض نتائج هذه الدوال على المتصفح، سنحتاج إلى ربطها بمسارات خاصة، تمامًا كما فعلنا في الدروس السابقة، ولكننا سنستخدم التعابير النظامية هذه المرة لتعيين نمط المسار الذي نرغب بربطه مع كل دالة في ملف العروض.

عزل مسارات التطبيق عن مسارات المشروع

قبل أن نبدأ عملية ربط المسارات بالعروض، سنتطرق إلى إحدى الممارسات التي يُنصح اتباعها بشدة عند تطوير التطبيقات باستخدام إطار العمل Django، ألا وهي عزل مسارات التطبيق عن مسارات المشروع.
تتمتع تطبيقات Django بعدم ارتباطها بالمشروع الذي يحتويها، بمعنى أنّه يمكنك استخدام تطبيق الاقتراعات هذا في أي مشروع ترغب به، دون الحاجة إلى إجراء أي تعديل في بنية وهيكلية التطبيق.
وتحقيق هذا الأمر لا يتطلب سوى عزل المسارات الخاصة بالتطبيق في ملف منفصل، ثم الإشارة إلى هذا الملف في ملف المسارات الرئيسي الخاص بالمشروع لتصبح مسارات التطبيق الخاصة جزءًا من مسارات ذلك المشروع.
ولعزل مسارات تطبيق الاقتراعات عن المسارات الرئيسية للمشروع، توجّه إلى ملف mysite/urls.py وعدّله ليصبح بالشكل التالي:

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', admin.site.urls),
]

قمنا في السطر الأول باستيراد الدالة include والتي ستعمل على تضمين المسارات الموجودة في ملف polls/urls.py وربطها بالمسار polls/، كما هو موضح في العنصر الأول من قائمة urlpatterns.
فعلى سبيل المثال، لو طلب المستخدم العنوان mypolls/ في المتصفح يبدأ إطار العمل في البحث عن هذه الكلمة في ملف urls.py الخاص بالمشروع، وفي حالة عدم العثور عليها تظهر صفحة خطأ للمستخدم تفيد بعدم وجود هذا العنوان.
وفي حالة استخدام الدالة include يضيف Django إلى مجال بحثه الملف الذي تشير إليه هذه الدالة، بمعنى أنه لو طلب المستخدم العنوان polls/3/ مثلًا فسيتم البحث أولًا عن عبارة polls في ملف mysite/urls.py الخاص بالمشروع الرئيسي، وما أن يتم العثور على العبارة المطلوبة تبدأ الدالة include بالعمل وتبدأ عملية البحث عن العبارة التالية لـ polls (الرقم 3 في مثالنا هذا) في ملف polls/urls.py الخاص بالتطبيق والذي تشير إليه الدالة.
ولعزل مسارات التطبيق في ملف منفصل، توجّه إلى مجلد polls وأنشأ فيه ملفًّا جديدًا باسم urls.py، ثم أضف فيه الشيفرة التالية:

from django.conf.urls import url
from . import views

urlpatterns = [
    # ex: /polls/
    url(r'^$', views.index, name='index'),
    # ex: /polls/5/
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    # ex: /polls/5/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    # ex: /polls/5/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

لاحظ أن بنية هذا الملف مشابهة بشكل كبير للملف mysite/urls.py، حيث يتم استيراد الدالة url في بداية الملف، كما أن قائمة المسارات urlpatterns مماثلة للقائمة الموجودة في ملف mysite/urls.py.
يعمل السطر الثاني في الشيفرة السابقة على استيراد ملف العروض views.py والموجود في مجلد polls والذي يضم في الوقت نفسه ملف المسارات هذا، لذا يمكن اختصار اسم المجلد باستخدام النقطة ..

كيف تعمل المسارات في Django

يستخدم Django المسارات كوسيلة للربط بين العنوان الذي يدخله المستخدم في شريط العناوين الخاص بالمتصفح وبين العروض التي تؤدي وظائف مختلفة ومتنوعة، فعندما يدخل المستخدم عنوانًا معينًا في شريط العناوين يبدأ Django بالبحث ضمن المسارات المتوفرة لديه في ملفات urls.py - كما ذكرنا قبل قليل - عن أي نمط يطابق المسار المدخل، فإن حصل تطابق بين العنوان الذي أدخله المستخدم وبين أحد المسارات ينفّذ Django العرض المرتبط بذلك المسار مباشرة.
أما وسيلة البحث التي يستخدمها Django فهي التعابير النظامية، وهي عبارة عن سلسلة من الرموز التي تكوّن نمطًا معيّنًا يستعمل للبحث في النصوص (المسارات في حالتنا هذه) عن أجزاء تطابق هذا النمط، وتتألف سلسلة الرموز هذه من مجموعة من الحروف أو الأرقام التي تساعد في البحث عن كلمة معينة أو عبارة أو رقم معين، وإلى جانب ذلك يمكن استخدام عدد من الرموز الخاصة التي تحمل دلالات معينة في التعبيرات النظامية مثل ^، $، ؟ وغيرها.

المعامل regex والتعابير النظامية

تمتلك دالة url أربعة معاملات، اثنان منها معاملات إلزامية وهما regex وview واثنان اختياريان هما kwargs و name.
والمعامل regex في دالة url عبارة عن سلسلة نصية خام تتضمن تعبيرًا نظاميًا، يستخدمه Django في مطابقة العناوين المدخلة من قبل المستخدم مع المسارات المتوفرة في ملفات urls.py.
لتوضيح كيفية استخدام التعابير النظامية في Django سنبدأ أولًا بدالة url في ملف mysite/urls.py:

url(r'^polls/', include('polls.urls')),

لاحظ أن المعامل الأول يبدأ بالرمز ^، وهو أحد الرموز الخاصة في التعابير النظامية، ويشير إلى وجوب ورود الكلمة التي تلي هذا الرمز في بداية الجملة، وفي حالتنا هذه يتم البحث عن العبارات التي تبدأ بـ polls/، وهذا يعني أن العبارات polls/30 و polls/q=44 و polls/polls/polls/ و polls/sport/football/worldcup/2014 تكون كلها مطابقة لهذا النمط، إذ أنّ العبارات كلها تبدأ بـ polls/.
عند استخدام الدالة include في هذا المسار، يبدأ Django بالبحث عن العبارات التي تبدأ بـ polls/ في ملف mysite/urls.py مضافًا إليها كل العبارات الموجودة في ملف polls/urls.py.
يستخدم الرمز الخاص $ للإشارة إلى وجوب ورود الكلمة التي تسبق هذا الرمز في نهاية الجملة. لاحظ المثال التالي:

url(r'^polls/$', views.index, name='index'),

سيبحث Django في هذه الحالة عن العبارات التي تكون فيها كلمة polls/ في بداية ونهاية الجملة في الوقت ذاته، بمعنى أن العبارات polls/30 و polls/q=44 و polls/polls/polls/ و polls/sport/football/worldcup/2014 لن تكون مطابقة لهذا النمط، إذ أن كلمة polls/ تقع في بداية هذه الجمل، ولكنها ليست في نهايتها، أما العبارة polls/polls/polls فليست مطابقة لأن الكلمة المطلوبة ليست في بداية ونهاية الجملة في الوقت ذاته، فكلمة polls/ الأولى تقع في بداية الجملة وليست في نهايتها، وكلمة polls/ الأخيرة موجودة في نهاية الجملة وليست في بدايتها، وبهذا لا يحصل التطابق.
لنرفع الآن من مستوى تعقيد السلاسل المستخدمة كتعابير نظامية، ونأخذ دالة url التي تربط المسار بالعرض detail في ملف polls/urls.py:

url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

يستخدم Django الأقواس لالتقاط النص الذي يطابق النمط المستخدم في التعابير النظامية، ويمكن إسناد هذه القيمة إلى متغير بالشكل التالي: ?P<variable_name>، وفي مثالنا هذا سيتم إسناد القيمة المطابقة للتعبير النظامي إلى المتغير question_id.
يتألف التعبير [0-9]+ من جزأين، الأول هو [0-9] ويطابق الأعداد التي تضم الأرقام من 0 إلى 9 حصرًا ولن يحدث التطابق في حال وجود أي حرف حتى مع وجود الأرقام، أما علامة + فهي إحدى الرموز الخاصة بالتعابير النظامية والتي تعني تكرار الأرقام مرة واحدة أو أكثر.
هذا يعني أن Django سيبحث عن أي عبارة تبدأ بأي عدد (مثلًا: 3، 20، 4003 تطابق النمط، لكن abc، 3b2، ac3 لن تطابق النمط)، وفي حال مطابقة النمط لعبارة معينة سيتم إسنادها إلى المتغير question_id المستخدم في دالة detail الموجودة في ملف polls/views.py.
للتأكد من ذلك، قم بتشغيل الخادوم الخاص بـ Django، من خلال سطر الأوامر، ثم أدخل العنوان التالي في المتصفح، ولاحظ النتيجة:

http://127.0.0.1:8000/polls/33/

ما حدث هنا، هو أنك بعد أن أدخلت العنوان السابق في المتصفح، بدأ Django في البحث في ملف mysite/urls.py عن أي نمط يطابق العنوان المدخل، وبعد أن وجد أن النمط ^polls/ مطابق لهذا العنوان، بدأ المعامل الثاني للدالة url بالعمل والذي يتضمن الدالة include التي توجّه Django للبحث مرة أخرى عن العبارات التي تلي الكلمة polls/ ضمن العنوان المدخل، وتتم عملية البحث في الملف الذي تشير إليه الدالة وهو polls/urls.py، وبعد أن وجد Django أن النمط [0-9]+ مطابق لـ 33 بدأ المعامل الثاني للدالة url enter code hereبالعمل وهو تنفيذ العرض المرتبط بهذا المسار (detail) والموجود في ملف views.py.
جرب تغيير الرقم (33) إلى أرقام أخرى، كذلك جرب كتابة حروف بدلًا من الأرقام ولاحظ النتائج.
جرّب الآن تعديل العنوان إلى الشكل التالي، ولاحظ النتيجة:

http://127.0.0.1:8000/polls/33/results/

يوضح الجدول التالي بعض التعابير النظامية والأنماط الناشئة من هذه التعابير:

التعبير النظامي النمط
[A-Z]+ الحروف الإنكليزية الكبيرة مع تكرارها لمرة واحدة على الأقل
[A-Za-z]+ الحروف الإنكليزية الكبيرة والصغيرة مع تكرارها لمرة واحدة على الأقل
[0-9]+ جميع الأرقام مع تكرار الرقم لمرة واحدة على الأقل
\w يطابق هذا النمط أي كلمة
\d يطابق هذا النمط أي رقم
[A-Za-z0-9]+ يطابق هذا النمط جميع الحروف الإنكليزية إضافة إلى الأرقام

للاطلاع بشكل أكبر على التعابير النظامية والرموز المستخدمة فيها، يمكن زيارة المواقع التالية:
* Regular-Expressions.info
* Regexr، يتيح هذا الموقع تجربة التعابير النظامية بصورة مباشرة في المتصفح.

المعامل name

المعامل name عبارة عن سلسلة نصية يمكن من خلالها تحديد اسم خاص بالمسار، وسنستفيد من هذا الاسم لاحقًا في الإشارة إلى المسار عند التعامل مع القوالب في الدروس القادمة.

خاتمة

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

المصدر:
توثيقات Django



1 شخص أعجب بهذا


تفاعل الأعضاء




يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن