File & Image Uploads
Django handles file uploads through FileField and ImageField on models, and FileInput widget on forms. Files are stored in MEDIA_ROOT and served via MEDIA_URL. Proper configuration is essential for both development and production.
20 min•By Priygop Team•Updated 2026
File Upload Setup
- MEDIA_URL = '/media/' — URL prefix for uploads
- MEDIA_ROOT = BASE_DIR / 'media' — Storage directory
- FileField(upload_to='folder/') — General file upload
- ImageField(upload_to='images/') — Image with validation
- request.FILES — Access uploaded files in views
- enctype='multipart/form-data' on <form> is REQUIRED
- Pillow package needed for ImageField: pip install Pillow
File Upload Example
File Upload Example
# settings.py
# MEDIA_URL = '/media/'
# MEDIA_ROOT = BASE_DIR / 'media'
# blog/models.py
# class Post(models.Model):
# title = models.CharField(max_length=200)
# image = models.ImageField(upload_to='posts/', blank=True)
# attachment = models.FileField(upload_to='attachments/', blank=True)
# blog/forms.py
# class PostForm(forms.ModelForm):
# class Meta:
# model = Post
# fields = ['title', 'content', 'image', 'attachment']
# blog/views.py
# def create_post(request):
# if request.method == 'POST':
# form = PostForm(request.POST, request.FILES) # Include FILES!
# if form.is_valid():
# form.save()
# return redirect('blog:list')
# else:
# form = PostForm()
# return render(request, 'blog/form.html', {'form': form})
# Template — MUST include enctype
# <form method="post" enctype="multipart/form-data">
# {% csrf_token %}
# {{ form.as_p }}
# <button type="submit">Upload</button>
# </form>
# Display uploaded image
# {% if post.image %}
# <img src="{{ post.image.url }}" alt="{{ post.title }}">
# {% endif %}
# urls.py — serve media in development
# from django.conf import settings
# from django.conf.urls.static import static
# urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)Tip
Tip
Use FormView for non-model forms. Override form_valid() and form_invalid() for custom processing logic.
Diagram
Loading diagram…
QuerySets are LAZY — no DB hit until evaluated.
Common Mistake
Warning
Using CBVs when a simple function view would be clearer. CBVs shine for standard CRUD — use FBVs for custom logic.
Practice Task
Note
(1) Create a FormView for a contact form. (2) Override form_valid for email sending. (3) Add success message.
Quick Quiz
Key Takeaways
- Django handles file uploads through FileField and ImageField on models, and FileInput widget on forms.
- MEDIA_URL = '/media/' — URL prefix for uploads
- MEDIA_ROOT = BASE_DIR / 'media' — Storage directory
- FileField(upload_to='folder/') — General file upload