مُقدّمة:
بعد أن تعرّفنا على أهم المفاهيم الأساسيّة حول التّحقق من مُدخلات المُستخدم ومكتبة WTForms في الدّرس السّابق، حان الوقت لاستغلال إضافة Flask-WTF مع المكتبة لإنشاء الصّنف الذي سيمثّل النّموذج.
كيف تعمل مكتبة WTForms ؟
من المهم أن تدرك بأنّ استخدام مكتبة WTForms يكون على عدّة مراحل:
- إنشاء صنف Class خاص ليُمثّل النّموذج
- تقديم النّموذج باستخدام إطار العمل Flask إلى ملف HTML
- عرض الحقول على صفحة HTML
- الوصول إلى المُدخلات بعد إرسال النّموذج من طرف المُستخدم
المرحلة الأولى تتم على ملف مُستقل عادة، بحيث يتم إنشاء الصّنف ثمّ تقوم باستيراده في الملفّ الذي يحتوي على الموجّهات.
المرحلة الثّانيّة والمرحلة الأخيرة تتمّان على الدّالة التّابعة للموجّه.
في المرحلة الثّالثة نستخدم مُحرّك القوالب Jinja لعرض النّموذج للمُستخدم.
سنقوم في هذا الدّرس بالتّعرّف على أول مرحلتين، أمّا ما تبقى فسيكون في الدّرس التّالي.
تعريف الصّنف المسؤول عن النّموذج
أفضل ميّزة في مكتبة WTForms هي تمكيننا من إنشاء النماذج دون كتابتها مُباشرة بلغة HTML، بل نكتبها على شكل أصناف بايثون عاديّة، فهذا رائع، ويعني بأنّنا سنتمكّن من إجراء العديد من العمليات قبل أو بعد تهيئة النّماذج بلغة بايثون ما يترك مجالا كبيرا للمرونة في إنشاء النّماذج والحقول والتّحقق منها، وبالتّالي فالعمل مع المكتبة مُريح أكثر من كتابة شيفرة HTML بنفسك.
وبما أنّنا سنتعامل مع النّماذج على أنّها أصناف، فإليك أولا صنفا بسيطا يُمثّل نموذج HTML يهدف إلى تمكين الزّائر من توفير اسم مُستخدم وكلمة مرور عبر حقلين ليتمكّن من تسجيل الدخول.
from flask_wtf import FlaskForm from wtforms import TextField, PasswordField from wtforms.validators import DataRequired class LoginForm(FlaskForm): username = TextField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()])
نسترد أولا الصّنف FlaskForm
الذي تحدّثنا عنه سابقا في الدّرس السّابق من إضافة Flask-WTF، بعدها نقوم باستيراد TextField
الذي يُعبّر عن حقل نصي في نماذج HTML، أي بمعنى آخر، الوسم <input>
مع الخاصيّة type=text
، ونسترد كذلك الصّنف الذي يُسمى PasswordField
الذي يعتبر حقلا لكلمة المرور أي الوسم <input>
مع الخاصيّة type=password
في لغة HTML، ولاحظ بأنّنا نسترد هذه الأصناف التّي تٌعبّر عن الحقول من مكتبة WTForms وليس من إضافة Flask-WTF.
بعدها نقوم باستيراد المُصَادِق DataRequired
من الوحدة validators
المتواجدة بالمكتبة WTForms، سيُمكّننا هذا المُصادق من التّحقق من أنّ الحقل لا يحمل قيمة فارغة عند إرسال البيانات (بمعنى آخر، سيُصبح الحقل مطلوبا).
بعد استيراد ما نحتاج إليه، سنقوم بإنشاء صنف باسم LoginForm
ليُمثّل النّموذج الخاص بتسجيل الدّخول، لاحظ بأنّ هذا الصّنف يرث من الصّنف FlaskForm
الذي قمنا باستيراده من إضافة Flask-WTF.
وبما أنّ النّموذج سيحتوي حقلين فقط، حقل لاسم المُستخدم وحقل آخر لكلمة المرور، ثمّ زر لتأكيد وإرسال البيانات Submit button، فقد قمنا بتعريفهما داخل الصّنف، إذ عرّفنا أولا حقل اسم المُستخدم بتعريف مُتغيّر باسم username
ليكون كائنا من الصّنف TextField
مع تمرير مُعاملين، الأول عبارة عن سلسلة نصيّة تُمثّل لصيقة الحقل أو Field Label، أمّا المُعامل الآخر فعبارة عن قائمة بالمُصادقين، وفي حالتنا فإنّ القائمة تحتوي على مُصادق واحد فقط وهو DataRequired()
لجعل الحقل مطلوبا (أي منع المُستخدم من إرسال الحقل فارغا).
نقوم بنفس الشيء مع حقل كلمة المرور، مع جعل الكائن من الصّنف PasswordField
لتظهر مُدخلات المُستخدم على شكل نجمات عوضا عن نص واضح، كما أنّنا نُشير إلى أنّه حقل مطلوب كذلك عبر تمرير DataRequired
كعنصر من قائمة إلى المُعامل validators
.
بالنّسبة لزر إرسال البيانات فسنقوم بكتابته مُباشرة بلغة HTML في ملفّ القالب.
أين توضع الشّيفرة المسؤولة عن النّماذج؟
يُمكنك بالطّبع وضعها أينما تشاء، المهم أن تتمكّن من استيراد كل صنف على ملفّ app.py
أو أي ملفّ يحمل المُوجّهات التّي ستتعامل مع النّماذج، ويُمكنك حتى وضعها في نفس الملفّ بحيث لن تحتاج إلى استيرادها، وسأعطيك مثالا بسيطا عن هذا المبدأ (كل شيء في ملفّ واحد) لاحقا.
لكن من المُفضّل دائما اتّباع أفضل المُمارسات Best practices وهي ما يقوم به الجميع والمنصوح به لتوفير طريقة تطوير موحّدة ولتسهيل قراءة شيفرتك على الآخرين، وأفضل ممارسة في ما يتعلّق بالأصناف المسؤولة عن نماذج HTML هي بوضع الشّيفرة المسؤولة عن النّماذج في ملف باسم forms.py
داخل مُجلّد التّطبيق لتوفير تقسيم منظّم للشّيفرة.
تقديم النّموذج من المُوجّه إلى قالب HTML
بعد أن قمنا بتعريف الصّنف، بقيت ثلاثة مراحل لإدارة النّموذج باستعمال مكتبة WTForms، وهذا الجزء يهم المرحلة الثّانيّة، وفيها سنقوم بتقديم النّموذج باستخدام الدّالة render_template
وذلك عبر إنشاء كائن من الصّنف LoginForm
الذي أنشأناه مُسبقا وتقديمه إلى القالب.
لتبسيط الأمور، سأجمع الصّنف LoginForm
و شيفرة التّطبيق في نفس الملف، وسيكون التّطبيق بسيطا ليفهمه الجميع.
الشّيفرة الكاملة ستكون كالتّالي (قمت بفصل شيفرة النّموذج وشيفرة التّطبيق بفاصل صغير):
from flask_wtf import FlaskForm from wtforms import TextField, PasswordField from wtforms.validators import DataRequired class LoginForm(FlaskForm): username = TextField('Username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()]) # --------------------------- from flask import Flask, render_template app = Flask(__name__) app.config['SECRET_KEY'] = 'T\x1f\x85\x9b\xfe^\x0f\x14\x9f\xa3x\xa4\xb5\x92\xbe' @app.route('/', methods=['GET', 'POST']) def form(): form = LoginForm() if form.validate_on_submit(): # Handle received data pass return render_template('form.html', form = form) if __name__ == "__main__": app.run(debug=True)
كما تُلاحظ أعلاه، قمنا بإنشاء تطبيق بسيط نسترد فيه كلا من الصّنف Flask
والدّالة render_template
، ثمّ ننشئ الكائن app
وبعدها نقوم بتحديد مفتاح سري لتتمكّن مكتبة WTForms من توليد حقل خفي للحماية من هجمات CSRF، وبعدها نقوم بتعريف المُوجّه ونُشغّل الخادوم في آخر سطرين.
أهم شيء في التّطبيق هو الموجّه الرّئيسي ومُحتوى الدّالة form
التي سنقوم من خلالها بتقديم ومُعالجة النّموذج وبياناته:
@app.route('/', methods=['GET', 'POST']) def form(): form = LoginForm() if form.validate_on_submit(): # Handle received data pass render_template('form.html', form=form)
أولا نقوم بتحديد أنواع الطّلبات التّي سيقبلها المُوجّه بتمرير قائمة إلى المعامل methods
لإخبار فلاسك بأنّ هذا المُوجّه سيستقبل كلا من طلبات GET
التّي ستُقدّم النّموذج وطلبات POST
التّي ستستقبل ومن ثمّ نُعالجها البيانات.
بعدها نقوم بتعريف الكائن form
من الصّنف LoginForm
، يُمكنك الآن تجاهل الشّرط if form.validate_on_submit()
لأنّه يهتم بمُعالجة البيانات والمُصادقة عليها ولن نقوم بُمعالجتها حاليا لكن عليك أن تعلم بأنّ المُعالجة ستتمّ في مكان التّعليق Handle received data
، في الأخير نقوم بتقديم الملفّ form.html
مع تمرير الكائن form
لنتمكّن من الوصول إليه في القالب.
خاتمة
أنهينا في هذا الدّرس أول مرحلتين من مراحل استخدام مكتبة WTForms للتحقّق من مُدخلات المُستخدم، فقد تعرّفنا على كيفيّة إنشاء الصّنف الذي يُمثّل النّموذج، وتعرّفنا على كيفيّة إنشاء كائن من الصّنف ثمّ تمريره لملفّ HTML، لذا سنستغل هذا الكائن في الدّرس القادم لنتمكّن من عرض النّموذج على مُتصفّح المُستخدم، وسنعرّف كذلك على كيفيّة الوصول إلى البيانات وعلى كيفيّة مُعالجتها واستغلالها بعد أن يملأ المُستخدم النّموذج ويُرسله.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.