اذهب إلى المحتوى

تطبيق عملي لتعلم جانغو - الجزء السادس: إدارة الجلسات Sessions


Ola Abbas

سنوسّع في هذا المقال موقع المكتبة المحلية LocalLibrary من خلال إضافة عدّاد زيارات يعتمد على الجلسات إلى الصفحة الرئيسية. يُعَد هذا مثالًا بسيطًا نسبيًا، ولكنه يوضح كيفية استخدام إطار عمل الجلسة لتوفير سلوك دائم للمستخدمين المجهولين في مواقعك الخاصة.

  • المتطلبات الأساسية: اطّلع على جميع المقالات السابقة من هذه السلسلة، بما في ذلك مقال العروض Views العامة والتفصيلية.
  • الهدف: فهم كيفية استخدام الجلسات.

يتيح موقع المكتبة المحلية LocalLibrary الذي أنشأناه سابقًا للمستخدمين تصفح الكتب والمؤلفين في صفحة الدليل Catalog، إذ يمكن لكل مستخدم الوصول إلى الصفحات وأنواع المعلومات نفسها عند استخدام الموقع أثناء توليد المحتوى ديناميكيًا من قاعدة البيانات.

يمكن أن ترغب في مكتبة حقيقية بتزويد المستخدمين بتجربة مُخصَّصة لكلٍّ منهم بناءً على استخدامهم السابق للموقع وتفضيلاتهم وغير ذلك، فمثلًا يمكنك إخفاء رسائل التحذير التي أُعلِم المستخدم بها مسبقًا في المرة التالية التي يزور فيها الموقع أو تخزين واحترام تفضيلاتهم، مثل عدد نتائج البحث التي يريد عرضها في كل صفحة.

يتيح لك إطار عمل الجلسة تنفيذ هذا النوع من السلوك، مما يسمح لك بتخزين واسترداد بيانات عشوائية على أساس كل زائر للموقع.

تتألف هذه السلسلة الفرعية من السلسلة الأشمل تعلم تطوير الويب من المقالات التالية:

ما هي الجلسات؟

تحدث جميع الاتصالات بين متصفحات الويب والخوادم باستخدام بروتوكول HTTP، وهو بروتوكول عديم الحالة Stateless، والذي يعني أن الرسائل بين العميل والخادم مستقلة تمامًا عن بعضها بعضًا، إذ لا توجد فكرة عن التسلسل أو السلوك المعتمد على الرسائل السابقة، لذا إذا أردتَ أن يكون لديك موقع يتعقّب العلاقات الجارية مع العميل، فيجب تطبيق ذلك بنفسك.

تُعَد الجلسات آليةًَ يستخدمها إطار عمل جانغو Django ومعظم شبكة الإنترنت لتعقّب الحالة بين الموقع ومتصفحٍ معين، وتتيح الجلسات تخزين البيانات العشوائية لكل متصفح، وإتاحة هذه البيانات للموقع كلما اتصل المتصفح، ويُشَار بعد ذلك إلى عناصر البيانات الفردية المرتبطة بالجلسة باستخدام "مفتاح" يُستخدم لتخزين البيانات واستردادها.

يستخدم جانغو ملف تعريف ارتباط Cookie يحتوي على معرّف جلسة خاص id لتحديد كل متصفح وجلسته المرتبطة بالموقع، ولكن تُخزَّن بيانات الجلسة الفعلية في قاعدة بيانات الموقع افتراضيًا، ويُعَد ذلك أكثر أمانًا من تخزين البيانات في ملف تعريف ارتباط، والتي تكون فيها أكثر عرضةً للمستخدمين الضارين. يمكنك ضبط جانغو لتخزين بيانات الجلسة في أماكن أخرى، مثل الذاكرة المخبئية cache والملفات وملفات تعريف الارتباط "الآمنة"، ولكن يُعَد الموقع الافتراضي خيارًا جيدًا وآمنًا نسبيًا.

تفعيل الجلسات

جرى تفعيل الجلسات تلقائيًا عندما أنشأنا موقع الويب الهيكلي.

يجري إعداد الضبط Configuration في الأقسام INSTALLED_APPS و MIDDLEWARE من ملف المشروع "locallibrary/locallibrary/settings.py" كما يلي:

INSTALLED_APPS = [
    # …
    'django.contrib.sessions',
    # …

MIDDLEWARE = [
    # …
    'django.contrib.sessions.middleware.SessionMiddleware',
    # …

استخدام الجلسات

يمكنك الوصول إلى السمة session ضمن عرضٍ View ما من المعامل request، إذ يُمرَّر الوسيط HttpRequest بوصفه أول وسيط إلى العرض. تمثل سمة الجلسة session الاتصال المحدَّد بالمستخدم الحالي، أو الاتصال بالمتصفح الحالي بصورة أدق كما يحدّده معرّف الجلسة في ملف تعريف ارتباط المتصفح لهذا الموقع.

تُعَد سمة session كائنًا يشبه القاموس dictionary يمكنك قراءته وكتابته عدة مرات في عرضك، مع تعديله بالطريقة التي تريدها، كما يمكنك تطبيق جميع عمليات القاموس العادية، بما في ذلك مسح جميع البيانات واختبار ما إذا كان المفتاح موجودًا والتكرار عبر البيانات وغير ذلك، ولكن ستستخدم غالبًا واجهة برمجة تطبيقات "القاموس" المعيارية فقط للحصول على القيم وضبطها.

توضح أجزاء الشيفرة البرمجية الآتية كيفية الحصول على بعض البيانات وضبطها وحذفها باستخدام المفتاح "my_car" المرتبط بالجلسة الحالية (المتصفح).

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

# الحصول على قيمة الجلسة باستخدام مفتاحها (مثل المفتاح‫ 'my_car')، إذ سيحدث خطأ KeyError إن لم يكن المفتاح موجودًا
my_car = request.session['my_car']

# الحصول على قيمة الجلسة، إذ تُضبَط القيمة الافتراضية إن لم تكن موجودة‫ ('mini')
my_car = request.session.get('my_car', 'mini')

# ضبط قيمة الجلسة
request.session['my_car'] = 'mini'

# حذف قيمة الجلسة
del request.session['my_car']

تقدّم واجهة برمجة التطبيقات API عددًا من التوابع الأخرى التي تُستخدَم غالبًا لإدارة ملف تعريف ارتباط الجلسة المرتبط، فمثلًا هناك توابع لاختبار أن ملفات تعريف الارتباط مدعومة في متصفح العميل، ولضبط والتحقق من تواريخ انتهاء صلاحية ملف تعريف الارتباط، ولمسح الجلسات منتهية الصلاحية من مخزن البيانات. يمكنك التعرف على واجهة برمجة التطبيقات الكاملة في توثيق جانغو الرسمي.

حفظ بيانات الجلسة

يحفظ جانغو افتراضيًا في قاعدة بيانات الجلسة فقط ويرسل ملف تعريف ارتباط الجلسة إلى العميل عند تعديل (تخصيص) الجلسة أو حذفها، فإذا أردتَ تحديث بعض البيانات باستخدام مفتاح الجلسة الخاص بها كما وضحنا سابقًا، فلا داعٍ للقلق بشأن ذلك، فمثلًا:

# ‫اُكتشِف السطر التالي بوصفه تحديثًا للجلسة، لذلك تُحفَظ بيانات الجلسة.
request.session['my_car'] = 'mini'

إذا حدّثتَ بعض المعلومات في بيانات الجلسة، فلن يدرك جانغو أنك أجريت تغييرًا على الجلسة ولن يحفظ البيانات، فإذا أردتَ مثلًا تغيير بيانات "wheels" في بيانات "my_car" كما يلي، فيجب تمييز الجلسة على أنها مُعدَّلة صراحةً:

# لم يُعدَّل كائن الجلسة مباشرة، إذ عُدِّلت البيانات ضمن الجلسة فقط، إذًا لن تُحفَظ تغييرات الجلسة
request.session['my_car']['wheels'] = 'alloy'

# ضبط الجلسة بوصفها مُعدَّلة لفرض حفظ تحديثات البيانات أو ملفات تعريف الارتباط
request.session.modified = True

ملاحظة: يمكنك تغيير السلوك بحيث يحدّث الموقع قاعدة بيانات أو يرسل ملف تعريف الارتباط في كل طلب من خلال إضافة:

SESSION_SAVE_EVERY_REQUEST = True

في إعدادات مشروعك "locallibrary/locallibrary/settings.py".

تطبيق عملي: الحصول على عدد الزيارات

سنحدّث مكتبتنا لإخبار المستخدم الحالي بعدد المرات التي زار فيها الصفحة الرئيسية لموقع المكتبة المحلية ليكون بمثابة مثالٍ بسيط واقعي.

افتح الملف ‎/locallibrary/catalog/views.py وضِف الأسطر التي تحتوي على num_visits في التابع index()‎ كما يلي:

def index(request):
    # …

    num_authors = Author.objects.count()  # ‫'all()‎' مُضمَّنة افتراضيًا

    # عدد الزيارات إلى هذا العرض، كما هو محسوب في متغير الجلسة
    num_visits = request.session.get('num_visits', 0)
    request.session['num_visits'] = num_visits + 1

    context = {
        'num_books': num_books,
        'num_instances': num_instances,
        'num_instances_available'
: num_instances_available,
        'num_authors': num_authors,
        'num_visits': num_visits,
    }

    # ‫عرض قالب index.html مع البيانات الموجودة في متغير السياق
    return render(request, 'index.html', context=context)

سنحصل أولًا على قيمة مفتاح الجلسة 'num_visits' مع ضبطها على القيمة 0 إن لم تكن مضبوطةً مسبقًا، ثم نزيد القيمة في كل مرة نتلقى فيها طلبًا ونخزّنها في الجلسة (للمرة التالية التي يزور فيها المستخدم الصفحة)، ثم يُمرَّر المتغير num_visits إلى القالب في متغير السياق.

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

أضف السطر الموضّح في نهاية الكتلة التالية إلى قالب HTML الرئيسي "‎/locallibrary/catalog/templates/index.html" في نهاية قسم "المحتوى الديناميكي Dynamic content" لعرض متغير السياق num_visits:

<h2>Dynamic content</h2>

<p>The library has the following record counts:</p>
<ul>
  <li><strong>Books:</strong> {{ num_books }}</li>
  <li><strong>Copies:</strong> {{ num_instances }}</li>
  <li><strong>Copies available:</strong> {{ num_instances_available }}</li>
  <li><strong>Authors:</strong> {{ num_authors }}</li>
</ul>

<p>
  You have visited this page {{ num_visits }} time{{ num_visits|pluralize }}.
</p>

لاحظ أننا نستخدم وسم القالب pluralize المبني مسبقًا في جانغو لإضافة "s" (التي تمثل صيغة الجمع في اللغة الانجليزية) عند زيارة الصفحة مرات متعددة.

احفظ التغييرات وأعِد تشغيل خادم الاختبار، إذ يجب تحديث عدد الزيارات في كل مرة تحدّث فيها الصفحة.

الخلاصة

تعرّفنا في هذا المقال على مدى سهولة استخدام الجلسات لتحسين تفاعلك مع مستخدمين مجهولين، وسنشرح في مقالاتنا القادمة إطار عمل الاستيثاق Authentication والترخيص Authorization (الإذن)، وسنوضح كيفية دعم حسابات المستخدمين.

ترجمة -وبتصرُّف- للمقال Django Tutorial Part 7: Sessions framework.

اقرأ المزيد


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

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...