When building web applications, file uploading is a common task. In this guide, we'll go over how to handle file uploads from users in Django, store those files in a MySQL database, and retrieve and display the files for preview and download.
Prerequisites
Before we start, ensure that you have the following:
- Django project with MySQL configured
- Basic understanding of Django models, views, and templates
Step 1: Setting Up The Model
We'll create a model that will handle file uploads and store the file details in our MySQL database.
models.py
pythonfrom django.db import models class UploadedFile(models.Model): file = models.FileField(upload_to='uploads/') uploaded_at = models.DateTimeField(auto_now_add=True) def __str__(self): return self.file.name
FileField
: This is used to store files in Django.upload_to='uploads/'
: Uploaded files will be stored in theuploads
directory within yourMEDIA_ROOT
.
Step 2: Configuring Settings
In your settings.py
, configure Django to store uploaded files and serve them during development.
pythonimport os MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') INSTALLED_APPS = [ # Other apps 'django.contrib.staticfiles', ]
Step 3: Creating A File Upload Form
We need to create a form to allow users to upload files.
forms.py
pythonfrom django import forms from .models import UploadedFile class FileUploadForm(forms.ModelForm): class Meta: model = UploadedFile fields = ['file']
Step 4: Handling the Upload In Views
Now let's create a view that handles the file upload and displays the list of uploaded files.
views.py
pythonfrom django.shortcuts import render, redirect from django.http import HttpResponse from .forms import FileUploadForm from .models import UploadedFile import os from django.conf import settings from django.http import FileResponse def file_upload_view(request): if request.method == 'POST': form = FileUploadForm(request.POST, request.FILES) if form.is_valid(): form.save() return redirect('file_list') else: form = FileUploadForm() return render(request, 'file_upload.html', {'form': form}) def file_list_view(request): files = UploadedFile.objects.all() return render(request, 'file_list.html', {'files': files}) def file_download_view(request, file_id): file = UploadedFile.objects.get(id=file_id) file_path = os.path.join(settings.MEDIA_ROOT, file.file.name) return FileResponse(open(file_path, 'rb'), as_attachment=True) def file_preview_view(request, file_id): file = UploadedFile.objects.get(id=file_id) file_path = os.path.join(settings.MEDIA_ROOT, file.file.name) if file.file.name.endswith(('.png', '.jpg', '.jpeg')): return render(request, 'file_preview.html', {'file': file}) return HttpResponse("Preview not available for this file type.")
file_upload_view
: Handles the file upload form.file_list_view
: Displays all uploaded files.file_download_view
: Allows users to download files.file_preview_view
: Provides a preview for image files (JPG, PNG, etc.).
Step 5: Creating Templates
We need three templates: one for the file upload form, one to list files, and one for previews.
file_upload.html
html<form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">Upload File</button> </form>
file_list.html
html<h2>Uploaded Files</h2> <ul> {% for file in files %} <li> <a href="{% url 'file_preview' file.id %}">{{ file.file.name }}</a> | <a href="{% url 'file_download' file.id %}">Download</a> </li> {% endfor %} </ul>
file_preview.html (for image previews)
html<h2>Preview File: {{ file.file.name }}</h2> <img src="{{ file.file.url }}" alt="{{ file.file.name }}">
Step 6: Setting Up URLs
Configure your URLs to map to the appropriate views.
App-level urls.py
pythonfrom django.urls import path from . import views urlpatterns = [ path('upload/', views.file_upload_view, name='file_upload'), path('files/', views.file_list_view, name='file_list'), path('files/download/<int:file_id>/', views.file_download_view, name='file_download'), path('files/preview/<int:file_id>/', views.file_preview_view, name='file_preview'), ]
Step 7: Handling Media Files In Development
To serve uploaded files during development, update urls.py
to serve media files.
Project-level urls.py
The project-level is the directory with the asgi.py, settings.py, wsgi.py and urls.py files.
pythonfrom django.conf import settings from django.conf.urls.static import static urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Step 8: Migrate the Database
After creating the model, run the migrations to add it to the MySQL database.
bashpython manage.py makemigrations python manage.py migrate
Conclusion
We have successfully set up file uploading in Django with the ability to store, retrieve, preview, and download files. The files are stored in the file system, while the metadata is saved in a MySQL database. This setup is easily extensible for different file types, and you can further customize the file handling process depending on your project's needs.