تمنح نماذج الويب web forms من صناديقٍ نصيّة وحقول نصوص مُتعدّدة الأسطر المستخدمين القدرة على إرسال البيانات إلى التطبيق لاستخدامها في تنفيذ أمرٍ ما، أو حتّى لإرسال محتوًى نصي كبير، فمثلًا يُمنح المستخدم في تطبيقات التواصل الاجتماعي حيزًا يمكِّنه من إضافة محتوًى جديد إلى صفحته الشخصية؛ كما يوجد أيضًا في صفحة تسجيل الدخول حقلٌ لإدراج اسم المستخدم وحقلٌ لإدراج كلمة المرور، إذ يستخدم الخادم (تطبيق فلاسك في حالتنا) هذه البيانات التي أدخلها المستخدم ليسجّل دخوله إذا كانت البيانات صحيحة أو يستجيب برسالة خطأ مثل "!Invalid credentials" لإعلام المستخدم بأن البيانات التي أدخلها خاطئة.
يُعد فلاسك إطار عمل للويب مبني بلغة بايثون، ويتميز بكونه صغير الحجم وسهل المعالجة، ويوفّر أيضًا عدّة أدوات وميزات من شأنها جعل إنشاء تطبيقات الويب في لغة بايثون أسهل.
سننشئ في هذا المقال تطبيق ويب مُصغّر لبيان كيفيّة استخدام نماذج الويب، إذ سيتضمّن صفحةً لإظهار رسائل مُخزّنةٍ مُسبقًا ضمن قائمة باستخدام بايثون، وصفحةً أُخرى لإضافة رسائل جديدة، كما سنستخدم الرسائل الخاطفة message flashing لإبلاغ المستخدمين بوجود خطأ لدى إدخالهم لبيانات غير صحيحة.
#مستلزمات العمل
قبل المتابعة في هذا المقال لا بُدّ من:
- توفُّر بيئة برمجة بايثون 3 محلية، مثبّتة على حاسوبك، وسنفترض في مقالنا أن اسم مجلد المشروع هو "flask_app".
- الفهم الجيد لأساسيات فلاسك، مثل مفهوم الوجهات routes ودوال العرض view في فلاسك، وفي هذا الصدد يمكنك الاطلاع على المقال كيفية بناء موقعك الإلكتروني الأول باستخدام إطار عمل فلاسك Flask من لغة بايثون لفهم مبادئ فلاسك.
- فهم أساسيات لغة HTML.
الخطوة الأولى - عرض الرسائل
سننشئ في هذه الخطوة تطبيق فلاسك بصفحة رئيسية لعرض رسائل مُخزنة أصلًا في قائمة من قواميس بايثون.
لذا سنفتح ملف جديد باسم "app.py" للتعديل عليه:
(env)user@localhost:$ nano app.py
وسنضيف الشيفرة التالية ضمنه، بغية إنشاء خادم فلاسك ذو وجهةٍ واحدة:
from flask import Flask, render_template app = Flask(__name__) messages = [{'title': 'Message One', 'content': 'Message One Content'}, {'title': 'Message Two', 'content': 'Message Two Content'} ] @app.route('/') def index(): return render_template('index.html', messages=messages)
ثمّ نحفظ الملف ونغلقه.
استوردنا في الشيفرة السابقة كلًا من الصنف Flask
الذي سنستخدمه لإنشاء نسخة من التطبيق باسم app
، ودالة تصيّير القوالب ()render_template
من حزمة فلاسك flask
، مُمررّين المتغير الخاص __name__
اللازم لتمكين فلاسك من إعداد بعض المسارات العاملة في الخلفية؛ أمّا عن تصيير القوالب، فننصحك بقراءة المقال كيفية استخدام القوالب في تطبيقات فلاسك Flask.
ثمّ أنشأنا قائمةً عامّة في بايثون باسم messages
، والتي تحتوي على قواميس بايثون، وفي كل قاموس أضفنا مفتاحين أساسيين، هما: title
لتخزين عنوان الرسالة، و content
لتخزين مضمونها، وما هذا إلّا مثال مُبسّط لآلية تخزين البيانات، إذ نستخدم في التطبيقات العملية الواقعية قاعدة بيانات لتُخزّن هذه البيانات بصورةٍ دائم سامحةً لنا بتعديلها واسترجاعها بسهولة وفعالية.
وبعد إنشاء قائمة بايثون، أنشأنا دالة العرض ()index
باستخدام المُزخرف ()app.route@
الذي يحوّل دوال بايثون الاعتيادية إلى دوال عاملة في فلاسك، وفيها تكون القيمة المعادة استدعاءً للدالة ()render_template
التي تُعلم فلاسك بأنّ الوجهة الحالية يجب أن تعرض في النتيحة قالب HTML باسم index.html (سننشئ ملف القالب هذا في الخطوات اللاحقة) ممررين له قيمة المتغير المُسمّى messages
والذي يحتوي على قائمة الرسائل messages
التي صرحنا عنها للتو مُسندين لها القيم اللازمة، وجعلناها متاحةً للاستخدام من قبل قالب HTML.
ننصحك في هذا الصدد بقراءة المقال How To Create Your First Web Application Using Flask and Python 3 لفهم أعمق لدوال العرض في فلاسك.
الآن، سننشئ مجلدًا للقوالب باسم "templates" ضمن المجلد "flask_app"، إذ سيبحث فلاسك ضمنه عن القوالب، وبعدها سننشئ ملف القالب الأساسي باسم "base.html" وفيه سنكتب الشيفرة الأساسية التي سترثها بقية القوالب لتجنّب تكرار الشيفرات:
(env)user@localhost:$ mkdir templates (env)user@localhost:$ nano templates/base.html
ومن ثمّ نكتب الشيفرة التالية ضمن الملف base.html لإنشاء قالب HTML الأساسي مع شريط تنقل وجزء مُخصّص للمحتوى:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %} - FlaskApp</title> <style> .message { padding: 10px; margin: 5px; background-color: #f3f3f3 } nav a { color: #d64161; font-size: 3em; margin-left: 50px; text-decoration: none; } </style> </head> <body> <nav> <a href="{{ url_for('index') }}">FlaskApp</a> <a href="#">About</a> </nav> <hr> <div class="content"> {% block content %} {% endblock %} </div> </body> </html>
نحفظ الملف ونغلقه.
يتضمّن القالب الأساسي كافّة الشيفرات المتداولة التي سنحتاجها في القوالب الأُخرى.
ستُستبدل لاحقًا كتلة العنوان title
بعنوان كل صفحة وكتلة المحتوى content
بمحتواها، أمّا عن شريط التصفح فسيتضمّن رابطين، الأوّل ينقل المُستخدم إلى الصفحة الرئيسية للتطبيق باستخدام الدالة المساعدة ()url_for
لتحقيق الربط مع دالة العرض ()index
، والآخر لصفحة المعلومات حول التطبيق في حال قررت تضمينها في تطبيقك.
لذا سنفتح ملف القالب المُسمى "index.html" وهو الاسم الذي حددناه في الملف app.py:
(env)user@localhost:$ nano templates/index.html
ونكتب ضمنه الشيفرة التالية:
{% extends 'base.html' %} {% block content %} <h1>{% block title %} Messages {% endblock %}</h1> {% for message in messages %} <div class='message'> <h3>{{ message['title'] }}</h3> <p>{{ message['content'] }}</p> </div> {% endfor %} {% endblock %}
ثمّ نحفظ الملف ونغلقه.
وسّعنا في الشيفرة السابقة ملف القالب "base.html"، واستبدلنا محتوى كتلة المحتوى content
مُستخدمين تنسيق العنوان من المستوى الأوّل <h1>
الذي يفي أيضًا بالغرض لعنوان الصفحة.
كما استخدما حلقة for
التكرارية وهي من ضمن تعليمات محرّك القوالب جينجا Jinja وذلك في السطر البرمجي {% for message in messages %}
بهدف التنقل بين الرسائل في القائمة messages
(والمُخزنة ضمن المتغير المسمّى message
)؛ إذ سنعرض عناوين الرسائل ضمن تنسيق عنوان من المستوى الثالث باستخدام الوسم <h3>
، ومحتواها ضمن تنسيق فقرة باستخدام الوسم <p>
، وكلاهما ضمن حافظة عناصر HTML باستخدام الوسم <div>
.
ولتشغيل تطبيق الويب الذي أنشأناه، وبعد التأكّد من وجودنا ضمن المجلد "flask_app" مع تفعيل البيئة الافتراضية، لا بُدّ من إرشاد فلاسك إلى موقع التطبيق (في حالتنا الملف ذو الاسم "app.py") وذلك باستخدام متغير بيئة فلاسك FLASK_APP
:
(env)user@localhost:$ export FLASK_APP=app
نضبط متغير بيئة فلاسك Flask_ENV
على الوضع development
لتشغيل التطبيق في وضع التطوير ما يمكنّنا من استخدام مُنقّح الأخطاء كما يلي (مع ملاحظة أنّنا نستخدم الأمر set
في بيئة ويندوز عوضًا عن الأمر export
):
(env)user@localhost:$ export FLASK_ENV=development
بعدها، سنشغل التطبيق باستخدام الأمر flask run
:
(env)user@localhost:$ flask run
وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، نذهب إلى الرابط التالي باستخدام المتصفح:
http://127.0.0.1:5000/
فتظهر الرسائل المُخزّنة أصلًا ضمن القائمة "messages" في الصفحة الرئيسية للتطبيق كما يلي:
ومع نهاية هذه الخطوة نكون قد أعددنا تطبيق الويب ليعرض الرسائل المُخزنة، أمّا في الخطوة التالية سنعدّ نماذج الويب اللازمة لنسمح للمستخدمين بإضافة رسائل جديدة إلى القائمة لعرضها في الصفحة الرئيسية للتطبيق.
الخطوة الثانية - إعداد نماذج الويب
سننشئ في هذه الخطوة صفحةً جديدةً في التطبيق تسمح للمستخدمين بإضافة رسائل جديدة إلى قائمة الرسائل من خلال نموذج ويب.
لذا سنفتح نافذة طرفية جديدة مع بقاء خادم التطوير قيد التشغيل.
ومنها نفتح الملف app.py:
(env)user@localhost:$ nano app.py
ونضيف الوجهة التالية إلى نهاية الملف:
# ... @app.route('/create/', methods=('GET', 'POST')) def create(): return render_template('create.html')
نحفظ الملف ونغلقه.
تتضمّن الوجهة /create
معامل طلبيات HTTP methods المتضمّن صفًا tuple هو ('GET', 'POST')
للتعامل معها سواءً بطريقة GET
، أو POST
، إذ أن طريقة "GET" هي الطريقة الافتراضية المُستخدمة لجلب البيانات من الخادم، مثل حالة طلب عرض الصفحة الرئيسية أو صفحة المعلومات حول التطبيق؛ أمّا طريقة "POST" فتُستخدم من قبل المتصفح عند إرسال نماذج الإدخال إلى وجهةٍ مُحدّدة، الأمر الذي سيغيّر من البيانات المُخزّنة في الخادم.
وفي مثالنا هذا سيُطلب عرض صفحة إنشاء رسائل جديدة "create" باستخدام طلب من النوع "GET"، إذ ستتضمّن هذه الصفحة نموذج ويب بحقول إدخال وزر إرسال، ولدى ملء النموذج من قبل المستخدم وإرساله، يُرسل طلب من النوع "POST" إلى الوجهة create/
، الذي يتعامل مع الطلب من حيث التحقّق من صحة البيانات المُدخلة للتأكّد من كون المُستخدم لم يرسل نموذجًا فارغًا، لتُضاف عندها هذه البيانات إلى قائمة الرسائل "messages".
تؤدي دالة فلاسك ()create
حاليًا مهمةً واحدة، وهي تصيّير قالب HTML باسم "create.html" لدى استقبالها لطلب من نوع GET، لذا سننشئ الآن هذا القالب وسنعدّل الدالة ()create
لتصبح قادرةً أيضًا على التعامل مع الطلبات من النوع POST اللازمة في الخطوة التالية.
لذا سنفتح ملف القالب المُسمّى "create.html":
(env)user@localhost:$ nano templates/create.html
ونكتب ضمنه الشيفرة التالية:
{% extends 'base.html' %} {% block content %} <h1>{% block title %} Add a New Message {% endblock %}</h1> <form method="post"> <label for="title">Title</label> <br> <input type="text" name="title" placeholder="Message title" value="{{ request.form['title'] }}"></input> <br> <label for="content">Message Content</label> <br> <textarea name="content" placeholder="Message content" rows="15" cols="60" >{{ request.form['content'] }}</textarea> <br> <button type="submit">Submit</button> </form> {% endblock %}
ثمّ نحفظ الملف ونغلقه.
وسّعنا في الشيفرة السابقة قالب base.html واستبدلنا كتلة المحتوى content
بكائن عنوان من المستوى الأوّل <h1>
الذي سيعمل مثل عنوان للصفحة، وعيّنا في وسم كائن النموذج <form>
قيمة السمة method
لتكون post
بمعنى أنّ بيانات النموذج ستُرسل إلى الخادم مثل طلب من نوع POST
.
وفي كائن النموذج أضفنا حقل إدخال نصي باسم title
وهو الاسم الذي سنستخدمه في التطبيق للوصول إلى بيانات نموذج العنوان، كما أسندنا القيمة {{ request.form['title'] }}
لسمة value
من الوسم <input>
، وهو أمرٌ مفيدٌ لتخزين البيانات التي يدخلها المستخدم مع إمكانية استعادتها في حال حدوث خطأ ما؛ فإذا نسي المستخدم مثلًا ملء الحقل النصي المُخصّص لمحتوى الرسالة content
وهو حقل مطلوب، فسيُرسل طلب إلى الخادم لإرجاع رسالة خطأ في الاستجابة، ولكن البيانات في العنوان لن نفقدها لأنها محفوظة في الكائن العام request
ويمكن الوصول لها من خلال القيمة ['request.from['title
.
أضفنا بعد حقل الإدخال المُخصّص لعنوان الرسالة، حقلًا نصيًا مُتعدّد الأسطر لمحتواها باسم content
وأسندنا أيضًا القيمة {{ request.form['content'] }}
لسمة value
لنفس السبب آنف الذكر.
ونهايةً أضفنا زر إرسال إلى نهاية النموذج.
الآن وبعد التأكد من كون خادم التطوير ما يزال قيد التشغيل، ننتقل إلى الوجهة الجديدة create/
باستخدام المتصفح:
http://127.0.0.1:5000/create
فتظهر صفحة إضافة رسالة جديدة “Add a New Message” مع حقل إدخال لعنوان الرسالة وحقل نصي مُتعدّد الأسطر لإدخال محتوى الرسالة، وزر لتقديم النموذج عند الانتهاء من إدخال البيانات.
يُرسل هذا النموذج طلبًا من نوع "POST" إلى دالة فلاسك ()create
، ولكن حتى الآن ما من شيفرة في الدالة للتعامل مع الطلب هذا، لذا لن يحدث شيء بعد تعبئة النموذج وإرساله> لذلك، سنكتب في الخطوة التالية الشيفرة اللازمة للتعامل مع طلب من النوع "POST" بعد إرسال النموذج، إذ سنتحقّق من صحة البيانات المرسلة (ليست فارغة)، كما سنضيف عنوان الرسالة ومحتواها إلى قائمة الرسائل "messages".
الخطوة الثالثة - التعامل مع الطلبات الواردة من نماذج الويب
سنتعامل في هذه الخطوة مع الطلبات الواردة من نماذج الإدخال إلى التطبيق، إذ سنعمل على الوصول إلى البيانات التي أرسلها المستخدم عبر نموذج الإدخال المُنشأ في الخطوة السابقة لإضافتها إلى قائمة الرسائل، كما سنستخدم الرسائل الخاطفة message flashing لإعلام المستخدم في حال إرسال بيانات غير صحيحة، فعندها ستظهر الرسالة لمرة واحدة وتختفي في الطلب التالي (مثل الانتقال إلى صفحة أُخرى) ومن هنا جاء سبب تسميتها بالخاطفة.
لذا سنفتح الملف app.py لتحريره:
(env)user@localhost:$ nano app.py
لا بُد أولًا من استيراد ما يلي من إطار العمل فلاسك:
-
الكائن
request
العام المسؤول عن الوصول إلى بيانات الطلب والتي ستُرسل من خلال نموذج HTML المبني في الخطوة السابقة. -
الدالة
url_for()
لتوليد عناوين الروابط. -
الدالة
flash()
لعرض رسالةٍ وامضة عند انتهاء معالجة الطلب، لإعلام المُستخدم في حال سير الأمور على نحوٍ سليم أو في حال وجود مشاكل مثل كون البيانات المُدخلة خاطئة. -
الدالة
redirect()
لإعادة توجيه المستخدم إلى موقعٍ آخر في المتصفح.
سنضيف هذه الاستيرادات إلى السطر الأوّل من الملف كما يلي:
from flask import Flask, render_template, request, url_for, flash, redirect # ...
تخزّن الدالة flash()
الرسائل في جلسة المتصفح لدى المستخدم، وهذا ما يتطلّب إعداد مفتاح أمان Secret Key، إذ سيُستخدم هذا المفتاح لجعل الجلسات آمنة، وبذلك يتمكّن فلاسك من الحفاظ على المعلومات عند الانتقال من طلبٍ إلى آخر، مثل حالة الانتقال من صفحة إنشاء رسالة جديدة إلى الصفحة الرئيسية، مع ملاحظة أن المستخدم يستطيع الوصول إلى المعلومات المُخزّنة في الجلسة، ولكنه لا يستطيع تعديلها إلّا إذا كان لديه مفتاح الأمان، وبالتالي لا يجب أن تسمح لأي أحدٍ بالوصول إلى مفتاح الأمان الخاص بك.
تذكّر أنّ مفتاح الأمان يجب أن يكون سلسلةً نصيةً عشوائية بطولٍ مناسب، إذ من الممكن توليد مفتاح أمان باستخدام التابع ()os.urandom
من الوحدة os
، إذ يعيد هذا التابع سلسلة من البايتات العشوائية المناسبة لاستخدامات التشفير (الحصول على سلسلة نصية خاصّة أو رقم خاص). للحصول على سلسلة نصية عشوائية باستخدام هذا التابع، سنفتح نافذة طرفية جديدة ومنها نفتح صَدفة بايثون التفاعلية باستخدام الأمر التالي:
(env)user@localhost:$ python
وضمن صَدفة بايثون التفاعلية سنستورد الوحدة os
من مكتبة بايثون المعيارية، وسنستدعي التابع ()os.urandom
كما يلي:
>>> import os >>> os.urandom(24).hex()
فنحصل في الخرج على سلسلة مُشابهة لما يلي:
'df0331cefc6c2b9a5d0208a726a5d1c0fd37324feba25506'
وبذلك يمكننا استخدام هذه السلسلة النصية مثل مفتاح أمان.
ولإعداد مفتاح أمان، سنضيف ضبط SECRET_KEY
إلى التطبيق من خلال الكائن app.config
، الذي سنضيفه مباشرةً بعد تعريف الكائن app
وقبل تعريف المتغير messages
، على النحو التالي:
# ... app = Flask(__name__) app.config['SECRET_KEY'] = 'your secret key' messages = [{'title': 'Message One', 'content': 'Message One Content'}, {'title': 'Message Two', 'content': 'Message Two Content'} ] # ...
ومن ثمّ نعدّل دالة العرض ()create
لتبدو كما يلي:
# ... @app.route('/create/', methods=('GET', 'POST')) def create(): if request.method == 'POST': title = request.form['title'] content = request.form['content'] if not title: flash('Title is required!') elif not content: flash('Content is required!') else: messages.append({'title': title, 'content': content}) return redirect(url_for('index')) return render_template('create.html')
تَمكَّنا باستخدام العبارة الشرطية التي توازن قيمة request.method
مع القيمة POST
من التحقُّق بأنّ التعليمات التالية لها لن تُنفّذ إلّا إذا كان الطلب الحالي هو فعلًا بطريقة POST
، ومن ثمّ قرأنا قيم العنوان والمحتوى المرسلين من الكائن request.form
الذي يمكِّننا من الوصول إلى بيانات نموذج الإدخال المُضمّنة في الطلب؛ ففي حال عدم إدخال قيمةٍ للعنوان، فسيتحقق الشرط if not title
وبالتالي ستظهر رسالة للمستخدم نعلمه من خلالها بأن العنوان مطلوب وذلك باستخدام الدالة ()flash
، وهذا ما يضيف هذه الرسالة إلى قائمة للرسائل الخاطفة والتي سنعرضها لاحقًا ضمن الصفحة بوصفها جزءًا من القالب الرئيسي "base.html"؛ وعلى نحوٍ مُشابه فيما يتعلّق بقسم المحتوى، ففي حال كان فارغًا، فسيتحقق الشرط elif not content
وبالتالي ستظهر رسالة للمستخدم نعلمه من خلالها بأن المحتوى مطلوب، وستُضاف هذه الرسالة أيضًا إلى قائمة الرسائل الخاطفة.
أمّا في حال وجود عنوان ومحتوى سليمين، فسيُضاف قاموس بايثون جديد إلى القائمة messages
بالعنوان والمحتوى المدخلين من قبل المستخدم وذلك اعتمادًا على السطر البرمجي ({messages.append({'title': title, 'content': content
، ومن ثمّ نعيد توجيه الطلب إلى الصفحة الرئيسية باستخدام الدالة redirect()
بتمرير الرابط الناتج عن التابع url_for()
الذي قد مررنا له القيمة index
وسيطًا.
ثمّ نحفظ الملف ونغلقه.
ننتقل إلى الوجهة create/
عن طريق المتصفح كما يلي:
http://127.0.0.1:5000/create
وبملء النموذج بعنوان اختياري ومحتوى ما، وحالما نرسل النموذج، ستظهر الرسالة الجديدة في الصفحة الرئيسية للتطبيق.
ونهايةً سنعرّض كافّة الرسائل الخاطفة ضمن الصفحة الرئيسية للتطبيق، كما سنضيف رابطًا في شريط التصفح للقالب الرئيسي base.html، للانتقال إلى صفحة إضافة رسالة جديدة مباشرةً وبسهولة، لذا سنفتح ملف القالب الرئيسي:
(env)user@localhost:$ nano templates/base.html
الآن، سنعدّل الملف من خلال إضافة وسم رابط <a>
جديد بعد رابط تطبيق فلاسك المتوضّع في شريط التصفُّح داخل الوسم <nav>
، ثمّ سنضيف حلقة تكرارية أعلى كتلة المحتوى مباشرةً لعرض الرسائل الخاطفة أسفل شريط التصفح، إذ يوفّر فلاسك هذه الرسائل من خلال دالة فلاسك الخاصة get_flashed_messages()
، وسنضيف ضمن الوسم <style>
السمة alert
لكل رسالة مُسندين إليها بعض الخصائص من CSS كما يلي:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} {% endblock %} - FlaskApp</title> <style> .message { padding: 10px; margin: 5px; background-color: #f3f3f3 } nav a { color: #d64161; font-size: 3em; margin-left: 50px; text-decoration: none; } .alert { padding: 20px; margin: 5px; color: #970020; background-color: #ffd5de; } </style> </head> <body> <nav> <a href="{{ url_for('index') }}">FlaskApp</a> <a href="{{ url_for('create') }}">Create</a> <a href="#">About</a> </nav> <hr> <div class="content"> {% for message in get_flashed_messages() %} <div class="alert">{{ message }}</div> {% endfor %} {% block content %} {% endblock %} </div> </body> </html>
ثمّ نحفظ الملف ونغلقه، وبإعادة تحميل الرابط "https://127.0.0.1:5000" في المتصفح، ستظهر الصفحة الرئيسية للتطبيق بشريط تصفُّح مُتضمّن للعنصر "Create" الذي يرتبط بالوجهة create/
الخاصّة بصفحة إنشاء رسالة جديدة.
ولنرى كيفية عمل الرسائل الخاطفة، ننتقل إلى صفحة "Create" ونضغط على زر الإرسال في النموذج دون ملء أي من حقلي العنوان أوالمحتوى، فتظهر رسالة كما هو مبين بالشكل:
وبالعودة إلى الصفحة الرئيسية نلاحظ أنّ الرسالة الخاطفة أسفل شريط التنقل قد اختفت، رغم عرضها على أنها جزء من القالب الأساسي، وهنا تكمن ميزتها، فلو لم تكن رسالة خاطفة لكانت ستُعرض في الصفحة الرئيسية أيضًا لأنها ترث من القالب الأساسي.
ولو أرسلنا النموذج مع عنوان ومحتوى فارغ، فستظهر رسالة تفيد بأن حقل المحتوى مطلوب "!Content is required"، وبالضغط على رابط تطبيق فلاسك FlaskApp في شريط التصفُّح نعود إلى الصفحة الرئيسية للتطبيق؛ وهنا إذا ضغطنا في المُتصفّح على زر الرجوع، سنجد أن الرسالة الخاطفة المُتعلقّة بكون المحتوى فارغ لا تزال موجودة، ذلك لأنّ الطلب السابق هو المحفوظ حاليًا؛ أما لو انتقلنا إلى صفحة إنشاء رسالة جديدة من شريط التصفّح فسيُرسل طلب جديد، وبذلك تُمحى مُدخلات النموذج القديمة ومعها الرسالة الخاطفة.
وبذلك نكون قد تعرّفنا على كيفية استلام مُدخلات المُستخدم والتحقّق من صحتها وإضافتها إلى مصدر البيانات (وهو قائمة بايثون في حالتنا).
ملاحظة: ستختفي الرسائل المُضافة إلى الفائمة "messages" في التطبيق بمجرّد توقّف الخادم، لأنّ قوائم بايثون تُحفظ فقط في الذاكرة (المؤقتة)، أمّا لحفظ الرسائل بصورةٍ دائمة فلا بدّ من استخدام قاعدة بيانات مثل SQLite، وفي هذا الصدد ننصحك بقراءة المقال كيفية استخدام علاقة نوع واحد-إلى-متعدد one-to-many مع إطار العمل فلاسك Flask ومحرك قواعد البيانات SQLite لمزيد من التفاصيل حول هذه الفكرة.
الخاتمة
أنشأنا في هذا المقال تطبيق فلاسك يتيح للمستخدمين إضافة رسائل إلى قائمة رسائل لعرضها في الصفحة الرئيسية للتطبيق. كما أنشأنا نموذج ويب وتعلمنا كيفية التعامل مع البيانات التي يرسلها المستخدم عن طريق هذا النموذج لإضافتها إلى قائمة الرسائل، كما استخدمنا الرسائل الخاطفة لإعلام المستخدم في حال إرسال بيانات غير صحيحة.
ترجمة -وبتصرف- للمقال How To Use Web Forms in a Flask Application لصاحبه Abdelhadi Dyouri.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.