🎯 الهدف من الدرس:
تعلم كيفية إنشاء نموذج يسمح للمستخدمين برفع ملفات (صور أو مستندات) إلى الخادم، وحفظها في مجلد محدد داخل المشروع، مع التحقق من نوع الملف قبل الحفظ.
1. 📁 تجهيز المشروع
هيكل المشروع سيكون بهذا الشكل:
flask_upload/
│
├── app.py
├── templates/
│ ├── index.html
│ └── upload.html
└── static/
└── uploads/- مجلد templates/ لتخزين الصفحات (HTML).
- مجلد static/uploads/ لحفظ الملفات المرفوعة.
- ملف app.py يحتوي على الكود الرئيسي للتطبيق.
2. 🧩 كود التطبيق (app.py)
from flask import Flask, render_template, request, redirect, url_for
import os
app = Flask(__name__)
# تحديد مسار المجلد الذي تُحفظ فيه الملفات
UPLOAD_FOLDER = 'static/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# تحديد أنواع الملفات المسموح برفعها
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# التحقق من وجود ملف في الطلب
if 'file' not in request.files:
return 'لم يتم اختيار أي ملف!'
file = request.files['file']
if file.filename == '':
return 'اسم الملف فارغ!'
if file and allowed_file(file.filename):
filename = file.filename
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
file.save(filepath)
return f'تم رفع الملف بنجاح: <a href="/{filepath}">{filename}</a>'
return 'الملف غير مسموح برفعه!'
return render_template('upload.html')
if __name__ == '__main__':
app.run(debug=True)
3. 🖥️ ملف القالب (upload.html)
<!DOCTYPE html>
<html lang="ar">
<head>
<meta charset="UTF-8">
<title>رفع الملفات</title>
</head>
<body>
<h2>📂 رفع ملف إلى الخادم</h2>
<form action="/upload" method="POST" enctype="multipart/form-data">
<label for="file">اختر الملف:</label><br><br>
<input type="file" name="file" id="file"><br><br>
<input type="submit" value="رفع">
</form>
</body>
</html>
4. 🧠 شرح الكود
enctype="multipart/form-data": ضروري لإرسال الملفات في النماذج.allowed_file(): دالة بسيطة تتحقق من امتداد الملف.file.save(filepath): تحفظ الملف في المسار المحدد.- المجلد uploads/ يجب أن يكون موجودًا مسبقًا داخل
static.
🧩 تمرين الدرس الثامن:
المطلوب منك:
1- عدّل الكود بحيث يعرض بعد رفع الملف:- اسم الملف
- نوعه (الامتداد)
- حجمه بالكيلوبايت
✅ حل تمرين الدرس الثامن: رفع الملفات والتحقق من الحجم والنوع
🔧 المطلوب في التمرين:
- عرض اسم الملف ونوعه وحجمه بعد الرفع.
- منع رفع الملفات التي يتجاوز حجمها 2 ميجابايت.
📄 الكود الكامل بعد التطوير:
from flask import Flask, render_template, request
import os
app = Flask(__name__)
# 📁 إعداد مجلد الحفظ
UPLOAD_FOLDER = 'static/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# 📏 تحديد الحد الأقصى للحجم (2 ميجابايت)
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024 # 2MB
# ✅ تحديد أنواع الملفات المسموح بها
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
def allowed_file(filename):
"""تحقق من امتداد الملف"""
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
return '❌ لم يتم اختيار أي ملف!'
file = request.files['file']
if file.filename == '':
return '⚠️ لم يتم اختيار ملف.'
if file and allowed_file(file.filename):
filename = file.filename
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
# 🧮 حساب حجم الملف قبل الحفظ
file.seek(0, os.SEEK_END)
file_size = file.tell() # الحجم بالبايت
file.seek(0) # إعادة المؤشر للبداية
# 🚫 رفض الملفات الأكبر من 2MB
if file_size > app.config['MAX_CONTENT_LENGTH']:
return '❌ الملف كبير جدًا! الحد الأقصى هو 2 ميجابايت.'
# 💾 حفظ الملف
file.save(filepath)
# استخراج النوع (الامتداد)
file_type = filename.rsplit('.', 1)[1].upper()
# تحويل الحجم إلى كيلوبايت
size_kb = round(file_size / 1024, 2)
return f"""
✅ تم رفع الملف بنجاح!<br><br>
📄 <b>الاسم:</b> {filename}<br>
📁 <b>النوع:</b> {file_type}<br>
⚖️ <b>الحجم:</b> {size_kb} KB<br><br>
<a href="/{filepath}" target="_blank">عرض الملف</a>
"""
return '❌ الملف غير مسموح بنوعه!'
return render_template('upload.html')
if __name__ == '__main__':
# إنشاء مجلد الرفع إذا لم يكن موجودًا
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.run(debug=True)
🧠 شرح التحسينات:
file.seek(0, os.SEEK_END) لحساب حجم الملف دون حفظه مؤقتًا.MAX_CONTENT_LENGTH يحد حجم الملفات المرفوعة على مستوى التطبيق.- بعد الحفظ، يُظهر البرنامج اسم الملف ونوعه وحجمه بطريقة أنيقة وواضحة.
🧩 تمرين إضافي (اختياري):
قم بتطوير النموذج بحيث:
- يعرض صورة مصغّرة (thumbnail) مباشرة بعد الرفع إذا كان الملف صورة.
- يظهر تنبيه مخصص (alert) بدلاً من النصوص العادية عند الخطأ.

