Django文件上传优化需求:实现分文件夹存储与唯一命名
Hey there! Let's tweak your Django file upload view to hit those two requirements you mentioned. Here's a straightforward solution that handles both unique folders and filenames without any conflicts:
First, update your imports to include the tools we'll need for creating unique paths and filenames:
from django.shortcuts import render from django.conf import settings import openpyxl import os import uuid from datetime import datetime
1. Creating Unique Upload Folders
We’ve got two practical options depending on your app’s needs:
- User-specific folders (great if you have authenticated users)
- Timestamp + UUID folders (works for anonymous users or one-off uploads)
Option A: User-Specific Folders
If your users log in, create a dedicated folder for each user using their ID or username:
def get_user_upload_folder(user): # Build the path to the user's folder inside media folder_path = os.path.join(settings.MEDIA_ROOT, 'user_uploads', str(user.id)) # Create the folder if it doesn't exist os.makedirs(folder_path, exist_ok=True) return folder_path
Option B: Timestamp-Based Unique Folders
For anonymous uploads, generate a one-of-a-kind folder using a date stamp and short UUID:
def get_unique_upload_folder(): # Combine current date and a short unique ID for the folder name date_str = datetime.now().strftime("%Y%m%d") unique_id = str(uuid.uuid4())[:8] # Shorten UUID for readability folder_path = os.path.join(settings.MEDIA_ROOT, 'uploads', f"{date_str}_{unique_id}") os.makedirs(folder_path, exist_ok=True) return folder_path
2. Generating Unique Filenames
To avoid overwriting files with identical names, we’ll pair a UUID with the original file’s extension. This ensures every uploaded file gets a unique identifier:
def get_unique_filename(original_filename): # Split the original name into base name and extension name, ext = os.path.splitext(original_filename) # Create a unique filename using UUID + original extension unique_filename = f"{uuid.uuid4()}{ext}" return unique_filename
Updated View Function
Now let’s put everything together in your index view. Just comment out the folder option you don’t need:
def index(request): if request.method == "GET": return render(request, 'myapp/index.html', {}) else: # Grab the uploaded file from the request (match your form's file input name!) excel_file = request.FILES.get('excel_file') if not excel_file: return render(request, 'myapp/index.html', {'error': 'No file selected for upload'}) # Choose your folder strategy: # Option A: User-specific folder (requires authentication) # if request.user.is_authenticated: # upload_folder = get_user_upload_folder(request.user) # else: # return render(request, 'myapp/index.html', {'error': 'Please log in to upload files'}) # Option B: Unique timestamp folder (works for all users) upload_folder = get_unique_upload_folder() # Generate a unique filename for the uploaded file unique_filename = get_unique_filename(excel_file.name) # Build the full path where the file will be saved file_path = os.path.join(upload_folder, unique_filename) # Save the file to disk with open(file_path, 'wb+') as destination: for chunk in excel_file.chunks(): destination.write(chunk) # Optional: Continue processing the Excel file with openpyxl wb = openpyxl.load_workbook(file_path) # ... add your existing Excel processing logic here ... return render(request, 'myapp/index.html', {'success': 'File uploaded successfully!'})
Quick Setup Checks
- Ensure your
settings.pyhasMEDIA_ROOTandMEDIA_URLconfigured:MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' - For development, add this to your project’s
urls.pyto serve uploaded files:from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # ... your existing URL patterns ... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
This setup guarantees every upload goes to a unique folder and gets a unique filename—no more overwriting files from different users, even if they upload files with the exact same name!
内容的提问来源于stack exchange,提问作者Cyley Simon

