التّعامل مع إطار Flask ومكتبة WTForms: التّحقق من مُدخلات المُستخدم باستخدام مُصادِقي WTForms
يُعد إطار Flask من أبرز أطر العمل الخفيفة (microframeworks) في تطوير تطبيقات الويب باستخدام لغة بايثون. يتميز Flask بسهولة الاستخدام وبنيته البسيطة، ما يجعله الخيار الأمثل للمطورين المبتدئين والمحترفين على حد سواء. ولأن تطبيقات الويب تعتمد بشكل أساسي على التفاعل مع المستخدمين من خلال النماذج (Forms)، فإن التحكم في مدخلات المستخدم والتحقق من صحتها يشكّلان محوراً رئيسياً في أي تطبيق ويب. في هذا السياق، تأتي مكتبة WTForms لتلعب دوراً بالغ الأهمية في تسهيل عملية إنشاء النماذج والتحقق من صحتها بشكل مرن واحترافي.
يتناول هذا المقال شرحاً موسعاً وعميقاً لكيفية دمج WTForms في إطار Flask مع التركيز على آلية التحقق من مدخلات المستخدم باستخدام أدوات التحقق أو ما يُعرف بالمُصادِقات (Validators). سيتم تناول مكونات النماذج، آلية عمل المصادقات، كيفية إنشاء مصادقات مخصصة، والتعامل مع الأخطاء بطريقة تجعل واجهة المستخدم آمنة وسلسة.
أولاً: نظرة عامة على WTForms
WTForms هي مكتبة بايثونية مستقلة تسمح بإنشاء نماذج باستخدام كائنات (Objects) تعتمد على الفئات (Classes)، وتفصل بين منطق التطبيق وواجهة المستخدم، مما يسهم في كتابة شفرة منظمة وقابلة للصيانة. تتميز WTForms بدعمها الكامل لآلية التحقق من صحة البيانات المُدخلة، مما يجعلها مثالية للاستخدام مع Flask من خلال حزمة التكامل Flask-WTF.
ثانياً: تثبيت المكتبات اللازمة
لبدء استخدام WTForms مع Flask، يجب أولاً تثبيت الحزم المطلوبة باستخدام pip:
bashpip install Flask Flask-WTF
بعد التثبيت، يمكن استيراد العناصر الأساسية من المكتبات وتهيئة التطبيق بطريقة تضمن تكاملاً فعالاً بين Flask وWTForms.
ثالثاً: تهيئة التطبيق وتفعيل CSRF
تحتاج نماذج WTForms إلى مفتاح سرّي (secret key) لتفعيل حماية CSRF (Cross Site Request Forgery)، وهي آلية أمنية أساسية تمنع التلاعب بالنماذج.
pythonfrom flask import Flask
app = Flask(__name__)
app.config['SECRET_KEY'] = 'مفتاح_سري_قوي_للغاية'
رابعاً: بناء نموذج باستخدام WTForms
تعتمد نماذج WTForms على تعريف الفئات (classes) التي ترث من FlaskForm. تحتوي هذه الفئات على الحقول المختلفة مثل StringField, PasswordField, BooleanField، وغيرها، بالإضافة إلى قائمة من المصادقات (validators) التي تُستخدم للتحقق من صحة المُدخلات.
مثال على نموذج تسجيل دخول:
pythonfrom flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length
class LoginForm(FlaskForm):
username = StringField('اسم المستخدم', validators=[DataRequired(), Length(min=4, max=25)])
password = PasswordField('كلمة المرور', validators=[DataRequired()])
submit = SubmitField('تسجيل الدخول')
في هذا المثال، يستخدم الحقل username مصادقين:
-
DataRequired: يتحقق من أن الحقل غير فارغ. -
Length: يتحقق من أن طول السلسلة النصية يتراوح بين 4 و25 حرفاً.
خامساً: عرض النموذج في واجهة HTML
يتم دمج النموذج مع قوالب Flask (عادة باستخدام Jinja2) عبر تمريره إلى القالب وإظهار الحقول يدوياً أو باستخدام حزمة form.hidden_tag() لتضمين حقل CSRF تلقائياً.
html<form method="POST">
{{ form.hidden_tag() }}
<p>
{{ form.username.label }}<br>
{{ form.username(size=32) }}<br>
{% for error in form.username.errors %}
<span style="color: red;">{{ error }}span>
{% endfor %}
p>
<p>
{{ form.password.label }}<br>
{{ form.password(size=32) }}<br>
{% for error in form.password.errors %}
<span style="color: red;">{{ error }}span>
{% endfor %}
p>
<p>{{ form.submit() }}p>
form>
سادساً: آلية التحقق من المُدخلات باستخدام Validators
المصادقات هي مكونات برمجية جاهزة تقوم بالتحقق من شروط معينة في مدخلات المستخدم. فيما يلي أبرز المصادقات الجاهزة في مكتبة WTForms:
| المصادق | الوظيفة |
|---|---|
DataRequired() |
يتحقق من أن الحقل غير فارغ |
Email() |
يتحقق من أن السلسلة تمثل بريداً إلكترونياً صالحاً |
Length(min, max) |
يتحقق من أن طول النص يقع ضمن المدى المحدد |
EqualTo('fieldname') |
يتحقق من تطابق قيمتين، مفيد لتأكيد كلمة المرور |
NumberRange(min, max) |
يتحقق من أن القيمة الرقمية ضمن النطاق المحدد |
URL() |
يتحقق من أن السلسلة تمثل رابطاً صالحاً |
سابعاً: إنشاء مُصادقات مخصصة
في بعض الأحيان، يحتاج المطور إلى التحقق من شروط خاصة لا توفرها المصادقات الجاهزة. يمكن إنشاء مصادق مخصص عن طريق تعريف دالة تستقبل النموذج والحقل وتقوم برفع استثناء إذا لم تتحقق الشروط.
مثال على مصادق يتحقق من عدم وجود كلمة “admin” في اسم المستخدم:
pythonfrom wtforms.validators import ValidationError
def validate_username_not_admin(form, field):
if 'admin' in field.data.lower():
raise ValidationError('لا يمكن استخدام "admin" في اسم المستخدم.')
class CustomForm(FlaskForm):
username = StringField('اسم المستخدم', validators=[DataRequired(), validate_username_not_admin])
ثامناً: التعامل مع الأخطاء وإظهارها في الواجهة
أحد الجوانب الهامة في التفاعل مع WTForms هو عرض الأخطاء للمستخدمين بطريقة واضحة. كل حقل يحتوي على قائمة errors يمكن عرضها بجانب كل عنصر في واجهة HTML. وبهذا تضمن التجربة السلسة للمستخدم.
تاسعاً: التحقق من صحة النموذج في route
يتم تمرير نموذج WTForms إلى دالة route، وعند استلام الطلب (POST)، يتم التحقق من صحة النموذج باستخدام form.validate_on_submit() التي تتحقق من كل المصادقات المرتبطة بالحقل.
pythonfrom flask import render_template, request
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# معالجة الدخول بعد التحقق من صحة المدخلات
return 'تم تسجيل الدخول بنجاح'
return render_template('login.html', form=form)
عاشراً: المصادقات المركبة والمترابطة
قد تحتاج بعض النماذج إلى تنفيذ مصادقات تعتمد على عدة حقول في وقت واحد. يمكن تحقيق ذلك من خلال override لطريقة validate() داخل النموذج.
pythonclass RegisterForm(FlaskForm):
password = PasswordField('كلمة المرور', validators=[DataRequired()])
confirm_password = PasswordField('تأكيد كلمة المرور', validators=[DataRequired()])
def validate(self):
if not super().validate():
return False
if self.password.data != self.confirm_password.data:
self.confirm_password.errors.append('كلمتا المرور غير متطابقتين.')
return False
return True
حادي عشر: استخدام WTForms مع قواعد البيانات
عند الربط مع قاعدة بيانات (مثل SQLAlchemy)، يمكن استخدام WTForms للتحقق من أن اسم المستخدم أو البريد الإلكتروني غير مسجل مسبقاً. يتطلب ذلك مصادقة مخصصة تستعلم من قاعدة البيانات.
pythondef validate_unique_email(form, field):
user = User.query.filter_by(email=field.data).first()
if user:
raise ValidationError('البريد الإلكتروني مستخدم بالفعل.')
class RegisterForm(FlaskForm):
email = StringField('البريد الإلكتروني', validators=[DataRequired(), Email(), validate_unique_email])
ثاني عشر: دعم الرسائل متعددة اللغات
WTForms تدعم تخصيص رسائل الخطأ لتناسب اللغة المستخدمة في الواجهة، من خلال تمرير الوسيط message إلى كل مصادق.
pythonusername = StringField('اسم المستخدم', validators=[DataRequired(message="الرجاء إدخال اسم المستخدم.")])
يمكن أيضاً استخدام ملفات ترجمة وتفعيلها باستخدام مكتبة Babel.
ثالث عشر: مقارنة بين التحقق في WTForms والتحقق في جافا سكريبت
بينما يعمل WTForms على التحقق من المدخلات في الجانب الخلفي (backend)، يمكن تكامله مع آليات التحقق على الجانب الأمامي (frontend) باستخدام JavaScript، مما يتيح تحسين تجربة المستخدم دون التخلي عن حماية السيرفر. يُوصى دائماً بالتحقق المزدوج في كلا الجانبين، نظراً لأن التحقق على الواجهة وحده قابل للتجاوز.
رابع عشر: ملاحظات أمنية هامة
-
يجب استخدام حماية CSRF في جميع النماذج لمنع هجمات الحقن.
-
يجب التحقق من جميع المدخلات بغض النظر عن مستوى حساسية البيانات.
-
يجب ألا تعتمد فقط على جافا سكريبت في التحقق من صحة البيانات، إذ يمكن تجاوزه بسهولة.
خامس عشر: مثال تطبيقي كامل
python# main.py
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, ValidationError
app = Flask(__name__)
app.config['SECRET_KEY'] = 'مفتاح_سري_عشوائي'
class LoginForm(FlaskForm):
username = StringField('اسم المستخدم', validators=[DataRequired(), Length(min=4, max=25)])
password = PasswordField('كلمة المرور', validators=[DataRequired()])
submit = SubmitField('تسجيل الدخول')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
return 'مرحباً بك، تم تسجيل الدخول.'
return render_template('login.html', form=form)
if __name__ == '__main__':
app.run(debug=True)
جدول بأكثر المصادقات استخداماً في WTForms
| اسم المصادق | الغرض | مثال الاستخدام |
|---|---|---|
DataRequired() |
التحقق من أن الحقل غير فارغ | DataRequired(message="هذا الحقل إجباري") |
Email() |
التحقق من صحة البريد الإلكتروني | Email(message="البريد غير صحيح") |
Length(min, max) |
تحديد مدى الطول المسموح للنص | Length(min=3, max=50) |
NumberRange(min, max) |
تحديد مدى رقمي للقيم العددية | NumberRange(min=1, max=100) |
EqualTo('fieldname') |
التحقق من تطابق مع حقل آخر | EqualTo('confirm_password') |
URL() |
التحقق من صحة الرابط المدخل | URL(message="الرابط غير صالح") |
الخاتمة
دمج مكتبة WTForms مع إطار Flask يوفر حلاً فعالاً، آمناً، ومنظماً لإدارة النماذج والتحقق من صحة المدخلات في تطبيقات الويب. من خلال استخدام المصادقات الجاهزة أو إنشاء مصادقات مخصصة، يمكن تحقيق درجات عالية من الأمان والموثوقية في البيانات المدخلة، مما ينعكس بشكل مباشر على جودة أداء التطبيقات وتفاعل المستخدمين معها.
المراجع:

