Of course! Handling file uploads in Python is a common task, typically done in a web application context. I'll guide you through the process using two popular and robust frameworks:

- Flask: A lightweight and flexible micro-framework, great for smaller projects and learning.
- Django: A high-level, "batteries-included" framework, excellent for larger, more complex applications.
I'll also cover best practices for security, which is critical when dealing with file uploads.
Core Concepts (The Same for Both Frameworks)
No matter which framework you use, the server-side process for handling a file upload generally follows these steps:
-
HTML Form: Your web page needs a special
<form>element with:method="post": File uploads must be sent using the POST method.enctype="multipart/form-data": This is essential. It tells the browser to encode the form data in a way that includes the file's binary data, not just text.- An
<input type="file">element for the user to select a file.
-
Server-Side Logic:
(图片来源网络,侵删)- The server receives the
multipart/form-datarequest. - It parses the request to separate the form fields (like text input) from the file data.
- It accesses the file object, which contains the file's name, content type, and the actual binary data.
- It saves this binary data to a specific location on the server's filesystem.
- The server receives the
-
Security Considerations:
- Validate the File: Check the file's extension or MIME type to prevent uploading malicious files (e.g.,
.php,.exe). - Sanitize the Filename: Prevent directory traversal attacks (e.g.,
../../../malicious.php). Use a library or a simple function to generate a safe, unique filename. - Limit File Size: Prevent denial-of-service attacks by limiting the maximum upload size.
- Scan for Malware: For production systems, integrate a virus scanner to check uploaded files.
- Validate the File: Check the file's extension or MIME type to prevent uploading malicious files (e.g.,
Example 1: Using Flask
Flask is very straightforward for handling file uploads.
Step 1: Project Setup
First, install Flask:
pip install Flask
Create a project directory and the necessary files:

/flask_upload_project
|-- app.py
|-- /static
| |-- style.css
|-- /templates
| |-- upload.html
| |-- success.html
Step 2: The HTML Templates
templates/upload.html
This is the form for uploading the file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-g">Upload a File</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>Upload a File</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="file">Choose a file:</label>
<input type="file" name="file" id="file" required>
</div>
<button type="submit">Upload</button>
</form>
</body>
</html>
templates/success.html
This page is shown after a successful upload.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">Upload Successful</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<h1>File Uploaded Successfully!</h1>
<p>Your file has been saved.</p>
<a href="/upload">Upload another file</a>
</body>
</html>
Step 3: The Flask Application (app.py)
This is where the magic happens. We'll include security measures like generating a random filename.
import os
from flask import Flask, render_template, request, redirect, url_for, flash
# --- Configuration ---
# Create a folder to store the uploaded files
UPLOAD_FOLDER = 'uploads'
# Allowed extensions
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'}
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# A secret key is needed for flashing messages
app.config['SECRET_KEY'] = 'a_very_secret_key'
# --- Helper Functions ---
def allowed_file(filename):
"""Check if the file extension is allowed."""
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
# --- Routes ---
@app.route('/')
def index():
"""Redirect to the upload page."""
return redirect(url_for('upload_file'))
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# Check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
# Secure the filename
filename = secure_filename(file.filename)
# Save the file to the upload folder
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('success'))
else:
flash('File type not allowed!')
return redirect(request.url)
return render_template('upload.html')
@app.route('/success')
def success():
return render_template('success.html')
if __name__ == '__main__':
# Make sure the upload folder exists
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.run(debug=True)
Note: You need to import secure_filename from werkzeug.utils for the security function. I've updated the code above to reflect this.
Step 4: Run the Application
python app.py
Now, open your browser and go to http://127.0.0.1:5000/upload. You should see the form. After uploading a valid file, you'll be redirected to the success page.
Example 2: Using Django
Django has a more built-in, but slightly more verbose, way of handling file uploads.
Step 1: Project Setup
First, install Django:
pip install Django
Create a new Django project and app:
django-admin startproject django_upload_project cd django_upload_project python manage.py startapp uploads
Configure the project:
-
django_upload_project/settings.py:- Add your new app to
INSTALLED_APPS:INSTALLED_APPS = [ # ... 'uploads', ] - Define the
MEDIA_URLandMEDIA_ROOT.MEDIA_ROOTis where Django will store uploaded files.MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
- Add your new app to
-
django_upload_project/urls.py:-
Include the URLs from your
uploadsapp and serve media files during development.from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('upload/', include('uploads.urls')), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
-
Step 2: Create the Model and Views
uploads/models.py
We'll create a simple model to store information about the uploaded file.
from django.db import models
class UploadedFile(models.Model):
file = models.FileField(upload_to='uploaded_files/')
upload_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.file.name
uploads/views.py
This view will handle both displaying the form and processing the upload.
from django.shortcuts import render, redirect
from .models import UploadedFile
def upload_file_view(request):
if request.method == 'POST':
# Get the file from the request
uploaded_file = request.FILES['file']
# Create a model instance and save the file
# Django handles saving to the 'uploaded_files/' subdirectory in MEDIA_ROOT
file_instance = UploadedFile(file=uploaded_file)
file_instance.save()
return redirect('success') # Redirect to a success page
# For a GET request, just show the form
return render(request, 'upload_form.html')
def success_view(request):
return render(request, 'success.html')
Step 3: Create the HTML Templates
Create a templates directory inside your uploads app and add these files:
uploads/templates/upload_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">Upload a File (Django)</title>
</head>
<body>
<h1>Upload a File</h1>
<form action="/upload/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>
<label for="id_file">Choose a file:</label>
<input type="file" name="file" id="id_file" required>
</div>
<button type="submit">Upload</button>
</form>
</body>
</html>
Note: Django's default form rendering includes a csrf_token, which is important for security.
uploads/templates/success.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">Upload Successful (Django)</title>
</head>
<body>
<h1>File Uploaded Successfully!</h1>
<p>Your file has been saved.</p>
<a href="/upload/">Upload another file</a>
</body>
</html>
Step 4: Create URL Configurations
uploads/urls.py (Create this file)
from django.urls import path
from . import views
urlpatterns = [
path('', views.upload_file_view, name='upload_file'),
path('success/', views.success_view, name='success'),
]
Step 5: Run the Application
First, create and apply database migrations for our new model:
python manage.py makemigrations python manage.py migrate
Then, run the development server:
python manage.py runserver
Open your browser and go to http://127.0.0.1:8000/upload/. You can upload files, and they will be saved in the media/uploaded_files/ directory.
Summary: Flask vs. Django for File Uploads
| Feature | Flask | Django |
|---|---|---|
| Simplicity | Very simple and direct. You handle everything manually. | More structured. The FileField and request.FILES handle parsing. |
| Configuration | Minimal. You just create a directory and save the file. | More involved. Requires settings for MEDIA_URL and MEDIA_ROOT. |
| Model Integration | None. You just save the file to the filesystem. | Excellent. The FileField in a model seamlessly saves files to MEDIA_ROOT and stores the path in the database. |
| Security | Manual. You must implement checks for file type and secure filenames. | Partially built-in. The FileField can validate extensions. You still need to be mindful of filenames and other security practices. |
Choose Flask if: You want a lightweight, simple solution for a small project or a quick prototype.
Choose Django if: You are building a larger application where you want to store file information in a database and leverage Django's built-in features and security best practices.
