نحتاج عادةً إلى قاعدة بيانات في تطبيقات الويب، وهي مجموعةٌ مُنطمّةٌ من البيانات نستخدمها لتخزين وتنظيم البيانات الدائمة، موفّرةً لنا إمكانية استرجاع هذه البيانات ومعالجتها بفعالية، إذ نحتاج مثلًا في تطبيق ما للتواصل الاجتماعي إلى قاعدة بيانات لتخزين بيانات المستخدم (من معلومات شخصية ومنشورات وتعليقات ومتابعين) لنتمكّن من معالجتها بفعالية، إذ توفّر قاعدة البيانات إمكانية إضافة بيانات جديدة إليها، أو استرجاع بيانات مُخزّنة أصلًا، أو التعديل عليها، أو حذفها بكل مرونة وذلك اعتمادًا على المتطلبات والشروط والظروف المُختلفة، ففي تطبيق ويب ما قد تكون هذه المتطلبات مثلًا هي حالة إضافة المُستخدم لمنشور جديد، أو حذف منشور سابق، أو حذف حسابه مع كافّة منشوراته أو مع الإبقاء عليها، بمعنى أنّ طريقة معالجة البيانات تعتمد أولًا وأخيرًا على الميزات التي يتيحها التطبيق، فمثلًا قد لا ترغب بالسماح لمُستخدمي تطبيقك بإضافة منشورات غير معنونة.
يُعد فلاسك إطار عمل للويب مبني بلغة بايثون، ويتميز بكونه صغير الحجم وسهل المعالجة، ويوفّر أيضًا عدد أدوات وميزات من شأنها إنشاء تطبيقات ويب في لغة بايثون.
أمّا MongoDB، فهو برنامج قواعد بيانات عام الأغراض ومستندي التوجّه document-oreiented من نوع NoSQL، الذي يستخدم المستندات المشابهة لصيغة JSON لتخزين البيانات. تتيح قواعد البيانات المُعتمدة على المستندات المشابهة لصيغة JSON تخطيطًا ديناميكيًا مرنًا لقاعدة البيانات مع الحفاظ على بساطتها على عكس العلاقات المتعددة بين الجداول المُستخدمة في قواعد البيانات العلّاقية، فعمومًا تتميز قواعد البيانات من النوع NoSQL بالتوسّع الأفقي، ما يجعلها مناسبةً للبيانات الضخمة وتطبيقات الوقت الحقيقي.
سنعمل في هذا المقال على بناء تطبيق ويب مصغر لإنشاء قوائم المهام ومن خلاله سنوضّح كيفية استخدام المكتبة PyMongo، وهي محرك قواعد بيانات يتيح إمكانية التخاطب مع قاعدة بيانات MongoDB باستخدام لغة بايثون، وسنستخدمها ضمن فلاسك Flask لتأدية مهام التطبيق الأساسية، مثل الاتصال بخادم قاعدة البيانات وإنشاء التجميعات Collections التي من شأنها تخزين مجموعة من المستندات في قاعدة البيانات MongoDB وإدخال البيانات ضمن تجميعة ما، إضافةً إلى جلب وحذف البيانات من التجميعات.
مستلزمات العمل
قبل المتابعة في هذا المقال لا بُدّ من:
-
توفُّر بيئة برمجة بايثون 3 محلية، مثبّتة على حاسوبك، وسنفترض في مقالنا أن اسم مجلد المشروع هو
flask_app
. - توفّر محرّك قواعد بيانات MongoDB مثبّتٍ على حاسوبك، وفي هذا الصدد ننصحك بقراءة المقال كيفية تثبيت وتأمين MongoDB على أوبونتو 18.04 للمزيد حول كيفية إعداد قاعدة بيانات MongoDB.
- الفهم الجيد لأساسيات فلاسك، مثل مفهوم الوجهات ودوال العرض والقوالب، وفي هذا الصدد يمكنك الاطلاع على المقالين كيفية بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask من لغة بايثون وكيفية استخدام القوالب في تطبيقات فلاسك Flask لفهم مبادئ فلاسك.
- فهم أساسيات لغة HTML.
الخطوة 1 - إعداد مكتبة PyMongo وإطار فلاسك
سنعمل في هذه الخطوة على تثبيت كل من فلاسك والمكتبة PyMongo.
لذا، وبعد التأكّد من تفعيل البيئة الافتراضية، نستخدم أمر تثبيت الحزم pip
لتثبيت كل من فلاسك ومكتبة PyMongo
على النحو التالي:
(env)user@localhost:$ pip install Flask pymongo
وبمجرّد انتهاء التثبيت بنجاح، سيظهر في نهاية الخرج سطر شبيه بما يلي مؤكدًا نجاح العملية:
Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 itsdangerous-2.0.1 pymongo-4.0.1
وبذلك نكون قد ثبتنا حزم بايثون اللازمة، وفيما يلي سنعمل على الاتصال بخادم قاعدة البيانات MongoDB وإنشاء تجميعة.
الخطوة 2 - الاتصال بخادم MongoDB وإنشاء تجميعة
سنستخدم في هذه الخطوة مكتبة PyMongo
لإنشاء عميل سنستخدمه في التخاطب مع خادم MongoDB، وإنشاء قاعدة بيانات، ومن ثم إنشاء تجميعة لتخزين المهام ضمنها.
الآن وبعد التأكّد من تفعيل البيئة الافتراضية، ننشئ ملفًا جديدًا باسم app.py
لتحريره ضمن المجلد flask_app
على النحو التالي:
(env)user@localhost:$ nano app.py
سيستورد هذا الملف الصنف والمساعدات الضرورية من حزمة فلاسك ومن مكتبة PyMongo
، إذ سنتخاطب مع خادم MongoDB بغية إنشاء قاعدة بيانات وتجميعة لتخزين المهام، لذلك سنكتب الشيفرات التالية ضمن الملف app.py
:
from flask import Flask from pymongo import MongoClient app = Flask(__name__) client = MongoClient('localhost', 27017) db = client.flask_db todos = db.todos
نحفظ الملف ونغلقه.
استوردنا في الشيفرة السابقة الصنف Flask
الذي سنستخدمه في إنشاء نسخة فعلية من التطبيق باسم app
، كما استوردنا الوحدة MongoClient
التي سنستخدمها لإنشاء كائن عميل باسم client
لنسخة قاعدة البيانات MongoDB، والذي يسمح لنا بالاتصال والتخاطب مع خادم MongoDB. عند استنساخ الدالة ()MongoClient
فإننا نمرّر لها كل من اسم مضيف خادم MongoDB وهو في حالتنا الحاسوب نفسه localhost
، ورقم المنفذ وهو هنا 27017
.
ملاحظة: من الضروري اتباع إجراءات أمان صارمة لدى تثبيت MongoDB وذلك باتباع الخطوات الواردة في المقال كيفية تثبيت وتأمين MongoDB على أوبونتو 18.04، وبمجرد تأمينها يمكنك البدء بضبط إعداداتها للتعامل مع الاتصالات عن بعد. بمجرّد تمكين خاصية الاستيثاق في MongoDB، سيتوجّب علينا لدى إنشاء نسخة من دالة ()MongoClient
بتمرير معاملين إضافيين لاسم المستخدم وكلمة المرور، وهما: username
و password
على النحو التالي:
client = MongoClient('localhost', 27017, username='username', password='password')
ثمّ استخدمنا في الشيفرة نسخة كائن العميل client
لإنشاء قاعدة بيانات MongoDB باسم flask_db
، وحفظ مرجع لها ضمن متغير باسم db
.
بعدها أنشأنا تجميعة باسم todos
ضمن قاعدة البيانات flask_db
باستخدام المتغير db
، إذ تُعد التجميعات مسؤولة عن تخزين مجموعة من المستندات في قاعدة البيانات MongoDB على غرار مبدأ الجداول في قواعد البيانات العلاقية.
نلاحظ إنشاء كل من قواعد البيانات والتجميعات في MongoDB اعتماديًا، بمعنى أنّه حتى لو جرى تنفيذ الملف app.py
، فلن تُنفّذ أي من الشيفرات الخاصة بقاعدة البيانات فعليًا إلى أن يُنشَأ المستند الأول.
سننشئ في الخطوة التالية تطبيق فلاسك مُصغّر يحتوي على صفحة تمكّن المستخدمين من إدخال مستندات مهامهم ضمن التجميعة المسماة todos
، حيث سيُنشأ ملف قاعدة البيانات flask_db
والتجميعة todos
ضمن خادم MongoDB بمجرّد إضافة أوّل مستند مهام.
وللحصول على قائمة بقواعد البيانات الموجودة حاليًا، نفتح نافذة طرفية terminal جديدة ونشغّل صدفة mongo
باستخدام الأمر التالي:
(env)user@localhost:$ mongo
فتظهر نافذة موجه أوامر، سنستخدم فيها الأمر التالي للتحقّق من قواعد البيانات الموجودة:
> show dbs
وفي حال كون MongoDB مُثبّتة حديثًا فلن يظهر ضمن القائمة في الخرج سوى قواعد البيانات admin
و config
و local
، كما نلاحظ عدم ظهور قاعدة البيانات flask_db
في هذه المرحلة.
أمّا الآن فسنترك صدفة mongo
قيد التشغيل ضمن نافذة الطرفية وننتقل إلى الخطوة التالية.
الخطوة 3 - إنشاء صفحة ويب لإضافة واستعراض المهام
سنعمل في هذه الخطوة على إنشاء صفحة ويب تسمح للمستخدمين بإضافة المهام واستعراضها ضمن نفس الصفحة.
لذا، سننشئ ملفًا باسم app.py
لتحريره وذلك أثناء كون البيئة البرمجية مُفعّلة، كما يلي:
(env)user@localhost:$ nano app.py
وفيه سنضيف بدايةً الاستدعاءات التالية من حزمة فلاسك:
from flask import Flask, render_template, request, url_for, redirect from pymongo import MongoClient # ...
استدعينا في الشيفرة السابقة الدالة المساعدة ()render_template
والتي سنستخدمها في تصيير قالب HTML، كما استدعينا الكائن request
لاستخدامه في الوصول إلى البيانات التي سيرسلها المستخدم عبر التطبيق؛ أما الدالة ()url_for
فستنشئ عناوين URLs، وستعيد الدالة ()redirect
توجيه المستخدم إلى صفحة التطبيق الرئيسية بعد إضافته مهمّةً جديدة.
والآن سنضيف الوجهة التالية إلى نهاية الملف app.py
، على النحو التالي:
# ... @app.route('/', methods=('GET', 'POST')) def index(): return render_template('index.html')
نحفظ الملف ونغلقه.
نمرّر في هذه الوجهة متغير صف tuple يحتوي على القيم ('GET', 'POST')
إلى المعامل methods
بغية السماح بكلا نوعي طلبيات HTTP وهما GET
و POST
؛ إذ تتخصّص الطلبيات من النوع GET
بجلب البيانات من الخادم؛ أمّا الطلبيات من النوع POST
فهي مُتخصّصة بإرسال البيانات إلى وجهة مُحدّدة، مع ملاحظة أنّ الطلبيات من النوع GET
هي الوحيدة المسموحة افتراضيًا، وحالما يطلب المستخدم الوجهة /
باستخدام طلبية من النوع GET
، سيُصيّر ملف قالب باسم index.html
.
سنعدّل هذه الوجهة لاحقًا لتتعامل أيضًا مع الطلبيات من نوع POST
اللازمة لدى ملء المُستخدمين نموذج الويب وإرساله بغية إنشاء مهام جديدة، ثمّ سننشئ مجلدًا للقوالب ضمن المجلد flask_app
، وسنفتح ضمنه ملف القالب index.html
كما يلي:
(env)user@localhost:$ mkdir templates (env)user@localhost:$ nano templates/index.html
وسنكتب الشيفرة التالية ضمن ملف القالب index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>FlaskApp</title> <style> .todo { padding: 20px; margin: 10px; background-color: #eee; } </style> </head> <body> <h1>FlaskTODO</h1> <hr> <div class="content"> <form method="post"> <p> <b><label for="content">Todo content</label></b> </p> <p> <input type="text" name="content" placeholder="Todo Content"></input> </p> <p> <b><label for="degree">Degree</label></b> </p> <p> <input id="degree-0" name="degree" required type="radio" value="Important"> <label for="degree-0">Important</label> </p> <p> <input id="degree-1" name="degree" required type="radio" value="Unimportant"> <label for="degree-1">Unimportant</label> </p> <button type="submit">Submit</button> </form> </div> </body> </html>
نحفظ الملف ونغلقه.
وبذلك أصبح لدينا صفحة HTML أساسية تحتوي على عنوان وبعض التنسيقات وترويسة ونموذج ويب، إذ ضبطنا الخاصية method
في نموذج الويب لتكون post
للدلالة على كون نموذج الويب سيرسل إلى الخادم طلبيات من النوع POST
، كما أضفنا إلى نموذج الويب هذا حقل إدخال نصي باسم content
، وهو مُخصّص لإدخال محتوى المهمّة، والذي سنستخدمه لاحقًا للوصول إلى بيانات العنوان في الوجهة /
، كما أضفنا للنموذج زري انتقاء باسم degree
ليحدّد من خلالهما المستخدم درجة أهمية كل عنصر مهام، بحيث يمكّنه من انتقاء خيار أهمية المهمّة عند إنشائها (مهمة Important أو غير مهمة Unimportant)، وأضفنا في نهاية النموذج زر أوامر Submit لتأكيد النموذج وإرساله.
سنعلم بعد ذلك فلاسك بموقع التطبيق (وهو الملف app.py
في هذه الحالة) باستخدام متغير البيئة FLASK_APP
وذلك أثناء وجودنا ضمن المجلد flask_app
ومع تفعيل البيئة الافتراضية، كما سنضبط متغير البيئة FLASK_ENV
المسؤول عن تحديد وضع التشغيل، وهنا قد اخترنا الوضع development
ما يعني أنّ التطبيق سيعمل في وضع التطوير مع تشغيل مُنقّح الأخطاء. لمزيدٍ من المعلومات حول مُنقّح الأخطاء في فلاسك ننصحك بقراءة المقال كيفية التعامل مع الأخطاء في تطبيقات فلاسك، ولتنفيذ ما سبق سنشغّل الأوامر التالية:
(env)user@localhost:$ export FLASK_APP=app (env)user@localhost:$ export FLASK_ENV=development
والآن سنشغّل التطبيق باستخدام الأمر flask run
:
(env)user@localhost:$ flask run
ملاحظة:لدى محاولة تشغيل التطبيق قد تظهر لك الرسالة 'ModuleNotFoundError: No module named 'pymongo
والتي تفيد بعدم وجود وحدة باسم pymongo
، ولإصلاح هذا الخطأ ما عليك سوى إلغاء تفعيل البيئة الافتراضية وإعادة تفعيلها مجدّدًا، وبعدها أعد تشغيل الأمر flask run
من جديد.
وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، نذهب إلى الرابط التالي باستخدام المتصفح:
http://127.0.0.1:5000/
فستظهر لك الصفحة الرئيسية للتطبيق متضمّنةً حقلًا لإدخال محتوى المهمّة وزريّ انتقاء لاختيار درجة الأهمية وزر أوامر لإرسال النموذج، كما في الشكل أدناه:
ولمزيدٍ من المعلومات المتقدمة ولتتعرّف على كيفية إدارة نماذج الويب بأمان ننصحك بقراءة مقال استخدام والتحقق من نماذج الويب ذات واجهة المستخدم التفاعلية في فلاسك باستخدام الإضافة Flask-WTF.
يرسل نموذج الإدخال هذا طلبًا من النوع POST
إلى الخادم، ولكن حتى هذه اللحظة لا توجد شيفرة مسؤولة عن معالجة هذا الطلب في الوجهة /
، وبالتالي لن يحدث شيء في حال ملء النموذج الآن وإرساله.
نفتح نافذة طرفية جديدة أثناء تشغيل الخادم، ثمّ نفتح الملف app.py
لتعديله ليتعامل مع الطلبات من النوع POST
المُرسلة من قبل المستخدم، بحيث يرسلها إلى تجميعة تخزين المهام ليعرضها ضمن صفحة التطبيق الرئيسية:
(env)user@localhost:$ nano app.py
ونعدّل الوجهة /
لتصبح كما يلي:
@app.route('/', methods=('GET', 'POST')) def index(): if request.method=='POST': content = request.form['content'] degree = request.form['degree'] todos.insert_one({'content': content, 'degree': degree}) return redirect(url_for('index')) all_todos = todos.find() return render_template('index.html', todos=all_todos)
احفظ الملف واغلقه.
وبعد هذه التغييرات، سيجري التعامل مع الطلبيات من النوع POST
باستخدام العبارة الشرطية 'if request.method == 'POST
، ففي حال تحقق الشرط سيُستخرج من الكائن request.form
كلًا من محتوى المهمّة ودرجة الأهمية التي أرسلها المستخدم.
استخدمنا التابع ()insert_one
على تجميعة المهام بغية إضافة مستند مهام إليها، كما وفرّنا بيانات المهمة ضمن قاموس بايثون عبر ضبط قيمة المفتاح المسمّى 'content'
لتساوي القيمة التي أدخلها المستخدم أصلًا ضمن الحقل النصي المُخصّص لمحتوى المهمّة في النموذج، كما ضبطنا قيمة المفتاح المسمّى 'degree'
لتساوي قيمة زر الانتقاء الذي اختاره المُستخدم. بعد ذلك، نعيد توجيه المُستخدم إلى الصفحة الرئيسية للتطبيق، إذ تُحدَّث هذه الصفحة لتعرض عنصر المهام الجديد المضاف.
استخدمنا التابع ()find
بغية عرض المهام المحفوظة خارج الجزء المسؤول عن التعامل مع الطلبيات من النوع POST من الشيفرة، والذي يعيد كافّة مستندات المهام المتوفرّة ضمن التجميعة todos
، إذ تُحفظ المهام المُستخرجة من قاعدة البيانات ضمن متغير باسم all_todos
، ثمّ عدلنا استدعاء التابع ()render_template
بحيث يمرر قائمة مستندات المهام إلى ملف القالب index.html
، والتي ستتواجد ضمن هذا القالب في متغير باسم todos
.
إذا حدّثت الصفحة الرئيسية للتطبيق، سيعرض المتصفح رسالة يطلب فيها تأكيد إعادة إرسال النموذج، وفي حال التأكيد سيُضاف عنصر المهام الذي حاولنا إرساله قبل إضافة الشيفرة المسؤولة عن التعامل مع الطلبيات من النوع POST إلى قاعدة البيانات، وذلك نظرًا لكون الشيفرة اللازمة للتعامل مع الطلبيات POST أصبحت متوفرّةً في الوجهة، ولكن بما أنّنا لم نضف حتى الآن شيفرة خاصّة بعرض عناصر المهام، فلن يظهر العنصر الذي أضفناه، ومن الممكن رؤية العنصر الأخير المُضاف عبر فتح صدفة mongo والاتصال مع قاعدة البيانات flask_db
باستخدام الأمر التالي:
> use flask_db
سنستخدم بعد ذلك الدالة ()find
لجلب كافّة عناصر المهام الموجودة في قاعدة البيانات:
> db.todos.find()
ففي حال إرسال أي بيانات ستظهر في الخرج هنا.
الآن، سنفتح ملف القالب index.html
لتعديله بغية عرض محتويات قائمة المهام todos
التي مررناها مُسبقًا إليه، على النحو التالي:
(env)user@localhost:$ nano templates/index.html
نعدّل الملف بإضافة وسم فاصل أفقي <hr>
وحلقة تكرارية for
من تعليمات جينجا jinja وذلك بعد الجزء الخاص بالنموذج، بحيث يصبح الملف كما يلي:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>FlaskApp</title> <style> .todo { padding: 20px; margin: 10px; background-color: #eee; } </style> </head> <body> <h1>FlaskTODO</h1> <hr> <div class="content"> <form method="post"> <p> <b><label for="content">Todo content</label></b> </p> <p> <input type="text" name="content" placeholder="Todo Content"></input> </p> <p> <b><label for="degree">Degree</label></b> </p> <p> <input id="degree-0" name="degree" required type="radio" value="Important"> <label for="degree-0">Important</label> </p> <p> <input id="degree-1" name="degree" required type="radio" value="Unimportant"> <label for="degree-1">Unimportant</label> </p> <button type="submit">Submit</button> </form> <hr> {% for todo in todos %} <div class="todo"> <p>{{ todo['content'] }} <i>({{ todo['degree']}})</i></p> </div> {% endfor %} </div> </body> </html>
نحفظ الملف ونغلقه.
أضفنا في الملف السابق وسم الفاصل الأفقي <hr> بغية فضل نموذج الويب عن قائمة المهام المعروضة، كما استخدمنا حلقة for
التكرارية ضمن السطر البرمجي الآتي:
{% for todo in todos %}
بغية المرور على كافة عناصر المهام في قائمة todos
، لتُعرض محتويات المهمّة ودرجة أهميتها ضمن وسم فقرة <p>.
بتحديث صفحة التطبيق الرئيسية وملء النموذج وإرساله، ستظهر المهمّة الجديدة المُضافة أسفل النموذج، أمّا في الخطوة التالية فسنعمل على إضافة زر أوامر يتيح للمستخدم إمكانية حذف إحدى المهام الموجودة أصلًا.
الخطوة 4 - حذف مهام
سنعمل في هذه الخطوة على إضافة وجهة تمكّن المستخدمين من حذف المهام باستخدام زر أوامر مُخصّص لهذا الغرض.
بدايةً، سنضيف وجهةً جديدةً للحذف، وهي /id/delete
تتعامل مع الطلبات من النوع POST، إذ ستستقبل دالة الحذف الجديدة delete()
رقم معرّف التدوينة ID المراد حذفها من خلال الرابط URL لتستخدم هذا المعرّف لحذف المهمّة الموافقة.
لحذف مهمة ما، سنجلب بدايةً معرّفها مثل سلسلة نصية والتي لا بُدّ من تحويلها إلى النوع ObjectId (نمط البيانات BSON وهو التمثيل الثنائي للنمط JSON) قبل تمريره إلى تابع الحذف من التجميعة، لذا يجب استيراد الصنف ()ObjectId
من الوحدة bson
، وهي المسؤولة عن التعامل مع ترميز وفك ترميز نمط البيانات BSON (أي JSON الثنائي).
الآن، سنفتح الملف app.py
لتحريره:
(env)user@localhost:$ nano app.py
وبدايةً سنضيف الاستدعاء التالي إلى بداية الملف، على النحو التالي:
from bson.objectid import ObjectId # ...
استُدعي الصنف ()ObjectId
لاستخدامه في تحويل المعرفات IDs إلى كائنات من النوع ObjectId.
سنضيف الآن الوجهة التالية إلى نهاية الملف app.py
:
# ... @app.post('/<id>/delete/') def delete(id): todos.delete_one({"_id": ObjectId(id)}) return redirect(url_for('index'))
نحفظ الملف ونغلقه.
استخدمنا في الشيفرة السابقة المزخرف app.post
المُقدّم في الإصدار 2.0.0 من فلاسك بدلًا من استخدام المزخرف app.route
المعتاد، والذي أضاف اختصارات للعديد من توابع HTTP الشائعة، فعلى سبيل المثال الأمر ("app.post("/login@
هو اختصار للأمر:
@app.route("/login", methods=["POST"])
ما يعني أن دالة العرض هذه تتعامل فقط مع طلبيات من النوع POST
، وبزيارة الوجهة /ID/delete
في المتصفّح سيظهر الخطأ 405 Method Not Allowed
لأن المتصفحات تستخدم طريقة GET
افتراضيًا للطلبات. لذلك، بغية حذف مهمة ما، سنضيف زر أوامر عندما يضغط المستخدم عليه، تُرسَل إلى الوجهة طلبية من النوع POST.
تستقبل الدالة معرّف مستند المهمّة المراد حذفها، ليُمرّر إلى التابع ()delete_one
المُطبّق على التجميعة todos
، ليُحوّل المعرّف المُستقبل من نوع سلسلة نصية إلى كائن من النوع ObjectId باستخدام الصنف ()ObjectId
المستورد سابقًا.
وبعد حذف مستند المهمة، نعيد توجيه المستخدم إلى الصفحة الرئيسية للتطبيق، أمّا الآن فسنعمل على تحرير ملف القالب index.html
لإضافة زر الأوامر الخاص بحذف المهام، على النحو التالي:
(env)user@localhost:$ nano templates/index.html
سنعدّل حلقة for
التكرارية بإضافة وسم نموذج <form> جديد، كما يلي:
{% for todo in todos %} <div class="todo"> <p>{{ todo['content'] }} <i>({{ todo['degree']}})</i></p> <form method="POST" action="{{ url_for('delete', id=todo['_id']) }}" > <input type="submit" value="Delete Todo" onclick="return confirm('Are you sure you want to delete this entry?')"> </form> </div> {% endfor %}
نحفظ الملف ونغلقه.
وبذلك يكون لدينا نموذج ويب يُرسل طلبيةً من النوع POST
إلى دالة العرض ()delete
، إذ مررنا المعامل ['todo['_id
لتحديد المهمّة المطلوب حذفها، كما استخدمنا التابع ()confirm
المتوفّر في متصفّح الويب لعرض رسالة تأكيد قبل إرسال الطلب.
الآن، بعد تحديث الصفحة الرئيسية للتطبيق، سيظهر زر أوامر لحذف المهمة أسفل كل عنصر مهام، وعند النقر عليه ستظهر رسالة لتأكيد عملية الحذف، ومن ثمّ سيعيد التطبيق التوجيه إلى صفحته الرئيسية فنلاحظ حذف المهمة فعلًا.
وبذلك أصبح تطبيق فلاسك يوفّر طريقةً لحذف المهام غير المرغوبة من قاعدة البيانات mongoDB.
ولتأكيد الحذف، نفتح صدفة mongo ونستخدم الدالة ()find
على النحو التالي:
> db.todos.find()
وعندها سنلاحظ أنّ العناصر المحذوفة لم تعد موجودةً في التجميعة todos
.
الخاتمة
أنشأنا في هذا المقال تطبيق ويب في فلاسك لإدارة المهام، إذ يتخاطب هذا التطبيق مع قاعدة بيانات MongoDB، وتعرفنا على كيفية الاتصال مع خادم قاعدة البيانات MongoDB، وأنشأنا تجميعات تُخزّن مجموعة من المستندات، واستعرضنا كيفية إدخال البيانات إلى تجميعة وجلبها أو حذفها منها.
ترجمة -وبتصرف- للمقال How To Use MongoDB in a Flask Application لصاحبه Abdelhadi Dyouri.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.