Home / Blogs

How to Work With Static & Media Files in Django


September 26, 2023


In the world of web development using Django, you’ll often find yourself dealing with different types of files like CSS, JavaScript, images, and files uploaded by users, such as images, videos, and documents. Efficiently managing these files is essential for ensuring your website or application runs smoothly and offers a great user experience.

When it comes to static files like CSS and JavaScript, Django has built-in tools that help you organize and serve these files to users’ browsers. This ensures that your web pages are styled and interactive as intended. On the other hand, user-uploaded media like profile pictures or document attachments require special handling. Django enables you to store and retrieve these files securely while keeping your application responsive.

In this guide, we’ll start with the fundamentals of working with static files and user-uploaded media in Django.

We’ll cover the basic techniques to get you started on the right foot. But we won’t stop there – we’ll also delve into more advanced methods that can take your web application to the next level. So, whether you’re just starting out or looking to enhance your Django skills, this guide will equip you with the knowledge you need to handle files effectively and create a top-notch web experience for your users.

To read more about creating custom admin interface in Django, refer to our blog How to Create Custom Admin Interface in Django in 2023

Static Files in Django

Static files are those that don’t change for each request, such as CSS, JavaScript, and images. Django comes with a powerful built-in system for managing static files. Here’s how to get started:

Directory Structure

By default, Django expects static files to be stored in a directory named static within your app’s directory. Create this folder and organize your static files within app-specific subdirectories.

For example:

└── static/
    ├── your_app/
    │   ├── css/
    │   ├── js/
    │   └── images/
    └── ...

Settings Configurations

In your project’s settings (settings.py), ensure that the STATIC_URL and STATIC_ROOT settings are correctly configured:

# settings.py

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATIC_URL: The URL prefix for serving static files during development.

STATIC_ROOT: The directory where collectstatic command will gather static files for production.

Serving Static Files

During development, Django’s built-in server will serve static files automatically. In production, you need to collect and serve static files using the collectstatic management command:

python manage.py collectstatic

Media Files in Django

Media files, including user-uploaded content like images and videos, require special handling to ensure proper storage and retrieval. Let’s dive into media handling in Django:

Directory Structure

Create a directory to store user-uploaded media files. In your project’s settings, configure the MEDIA_URL and MEDIA_ROOT settings:

# settings.py

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Model Configuration

To handle media files, modify your models to include fields that can store file paths. For example, to allow users to upload profile pictures:

from django.db import models

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    profile_picture = models.ImageField(upload_to='profile_pics/')


A field to store images. The upload_to parameter defines the subdirectory within MEDIA_ROOT where files will be stored.

Form configuration

Create a form to handle user uploads:

from django import forms

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ['profile_picture']

View and Template

In your view, process the form and save the uploaded file:

def upload_profile_picture(request):
    if request.method == 'POST':
        form = UserProfileForm(request.POST, request.FILES)
        if form.is_valid():
            # Redirect or render success page
        form = UserProfileForm()
    return render(request, 'upload_profile.html', {'form': form})

In your template (upload_profile.html), include the form and handle file uploads:

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Upload</button>

To read more about to build a custom user model in Django, refer to our blog How to Build a Custom User Model in Django


In conclusion, mastering the handling of static files and media in Django opens up a world of possibilities for creating dynamic and engaging web applications. By following the steps outlined and grasping the core concepts, you’ve gained the ability to efficiently manage both the visual components of your site and user-uploaded content.

As you delve further into the realm of Django development, consider venturing into advanced optimizations like utilizing Content Delivery Networks (CDNs) to expedite the loading of static resources globally. Embracing third-party media storage solutions will also enhance the performance and scalability of your application, ensuring a seamless experience for users as your platform gains traction.

Horilla Editorial Team Author

Horilla Editorial Team is a group of experienced writers and editors who are passionate about HR software. We have a deep understanding of the HR landscape and are committed to providing our readers with the most up-to-date and informative content. We have written extensively on a variety of HR software topics, including applicant tracking systems, performance management software, and payroll software etc. We are always looking for new ways to share our knowledge with the HR community. If you have a question about HR software, please don't hesitate to contact us.