Django file upload

Prerequisites

Django File Upload

  • Uploading files is a common requirement in many web applications, whether it's for user profiles, content management, or data storage.
  • Django makes file uploads seamless by providing powerful tools like FileField, ImageField, and form handling that automate much of the process.

Key Benefits of Django File Upload

  • Easy setup: Quickly configure file handling with Django's built-in fields.
  • Scalable management: Django provides flexible storage backends, including support for local storage and cloud services (e.g., Amazon S3, Google Cloud).
  • Security features: Django includes several built-in security measures to safely upload and manage files.

HTML Forms

  • HTML Forms are the standard way for users to submit data to a web server.
  • Forms use the <form> element, which wraps around input fields and defines the method and action.
  • Method: Specifies the HTTP method used (commonly POST or GET).
  • Action: Defines the URL where form data is submitted.
  • Common input types include text fields, checkboxes, radio buttons, and file uploads.

File Upload in HTML Forms

  • HTML Forms allows users to upload files from their local machine.
  • To enable file uploads, the form's enctype attribute must be set to multipart/form-data.
  • The <input> element with type="file" is used to select the file.
<form method="POST" action="/upload" enctype="multipart/form-data">
  <input type="file" name="file-upload">
</form>

Coding - File Upload

Update media settings

  • open the settings file my_project/settings.py and media settings.
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

Create a Model for File Upload

  • To handle file uploads, we will need to define a model with a FileField or ImageField.

  • Define a profile model which stores user bio and profile pic.

my_app/models.py

from django.db import models
from django.contrib.auth import get_user_model


class Profile(models.Model):
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
    bio = models.CharField(max_length=100, blank=True)
    profile_picture = models.ImageField(upload_to='profiles/', blank=True, null=True)

    def __str__(self):
        return self.user.first_name
  • Create the migrations for the above model using command python manage.py makemigrations
  • Apply the migrations using the command python manage.py mgirate
  • In above code, upload_to='profiles/' specifies that the uploaded files will be stored in a subdirectory called profiles under the MEDIA_ROOT.

Create File Upload Form

  • upload form allow user to select and upload the files.
  • open the file my_app/forms.py and add below code to it.

my_app/forms.py

from django import forms
from .models import Profile

class ProfileForm(forms.ModelForm):
  bio = forms.CharField(widget=forms.Textarea)

  class Meta:
    model = Profile
    fields = ['bio', 'profile_picture']

Add Profile Upload View

  • It uses the ProfileForm and handles the user's profile pic file upload
  • open the file my_app/views.py and add below code to it.
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect

@login_required
def user_profile(request):
    profile, created = Profile.objects.get_or_create(user=request.user)

    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES, instance=profile)
        if form.is_valid():
            form.save()
            return redirect('profile')
    else:
        form = ProfileForm(instance=profile)
    context = {'form': form, 'profile': profile}
    return render(request, 'profile.html', context)

Add File Upload Template

  • File upload template defines the form and content type of the form
  • It also defines the action url and request type POST
  • Create template templates/profile.html and below contents to it.

templates/profile.html

<html>
<head>
  <title>Update Profile</title>
</head>
<body>
  <h2>Update Profile</h2>
  <form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
  </form>
  <hr>
  {% if profile.profile_picture %}
  <img src="{{ profile.profile_picture.url }}" alt="Profile Picture" style="width:150px;height:150px;">
  {% endif %}
</body>
</html>

Update file upload urls

  • open the application urls.py file and configure the profile view.
  • open the file my_app/urls.py and add below content to it.

my_app/urls.py

from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from . import views

urlpatterns = [
  ...
  path('profile/', views.user_profile, name='profile'),
  ...
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  • above code will also serve media files for the development.

Test the file upload view

  • Open the url http://localhost:8000/profile/
  • Fill out the info and browse the image file to upload.
  • Submit the form and see that it renders the uploaded image.