Django Interview Questions 16-20 (Static Files, Media, Sessions, Caching)

Hello! In our previous lessons, we explored the MVT architecture, models, views, and forms. We learned how to build a data-driven application.

Now, we'll focus on the equally important concepts of serving and optimizing your application. This lesson covers how Django handles files (static vs. media), how it "remembers" users between requests (sessions), and the critical techniques for making your app faster (caching). These are essential topics for building professional, production-ready websites.

16. How are static files handled in Django?

This is a two-part answer: how it works in development vs. production.

Static files are the "application files" that you, the developer, provide. This includes all your CSS, JavaScript, fonts, and images (like your site's logo). They are part of your project's code.

Analogy: Static files are like the uniforms, printed menus, and logos for a restaurant chain. They are designed, packaged, and shipped with each new restaurant (deployment).

1. In Development:

In `settings.py`, you tell Django where to find your static files:

  • `STATIC_URL`: The URL prefix for your static files (e.g.,`/static/`).
  • `STATICFILES_DIRS`: A list of folders where Django should look for static files (e.g., a top-level `static/` directory).

When `DEBUG = True`, Django's built-in server is smart enough to find and serve these files for you automatically.

2. In Production (`DEBUG = False`):

In production, your Python app (Django) should not serve static files. This is very inefficient. You want your fast web server (like Nginx) to handle this.

To make this work, you must first run the `collectstatic` command:

$ python manage.py collectstatic

This command copies all static files from all your app folders (`STATICFILES_DIRS`) and puts them into one single folder defined by your `settings.py`:

  • `STATIC_ROOT`: The single directory where all static files will be collected for production (e.g., `/var/www/my-site/static/`).

You then configure Nginx to serve all requests to `/static/` directly from that `STATIC_ROOT` folder, bypassing Django entirely.

Sample Output of `collectstatic`:

131 static files copied to '/var/www/my-site/static'.

17. Difference between static files and media files.

This is a critical distinction in Django. Both are "files," but they have completely different origins and purposes.

Analogy: Let's use the restaurant again.

  • Static Files: These are the brand's assets: the official logo, the printed menus, the staff uniforms. They are created by the company (the developer) and are the same for every restaurant.
  • Media Files: These are files uploaded by users: a customer's profile picture for their loyalty account, a photo they post in a review. They are dynamic, untrusted, and not part of the application's code.
FeatureStatic FilesMedia Files
SourceProvided by the developer.Uploaded by the user at runtime.
Trust LevelTrusted. Part of the application code.Untrusted. Must be validated.
Example`style.css`, `logo.png`, `main.js``user_avatar.jpg`, `uploaded_report.pdf`
`settings.py` (URL)`STATIC_URL` (e.g., `/static/`)`MEDIA_URL` (e.g., `/media/`)
`settings.py` (Path)`STATIC_ROOT` (for `collectstatic`)`MEDIA_ROOT` (where uploads are saved)

18. What are Django sessions and how do they work?

The HTTP protocol is stateless. This means every request is independent, and the server forgets you the moment it sends a response.

The Session Framework is the mechanism Django uses to "remember" a user between requests. It allows you to store arbitrary data for each visitor.

Analogy: The Coat Check
This is the best way to think about it:

  • 1. You (a user) visit the site and log in. You are "giving your coat" (your `user_id`) to the coat check clerk (Django).
  • 2. The clerk stores your coat in a cubby (the session storage, e.g., the `django_session` database table).
  • 3. The clerk gives you a ticket (a cookie sent to your browser with a unique `sessionid`).
  • 4. You go to other pages. On every new request, you show your ticket (the `sessionid` cookie).
  • 5. Django's `SessionMiddleware` reads the ticket, goes to the storage, finds your coat (your data), and attaches it to the `request` object.
  • 6. Your view can then simply check `request.user` or `request.session` to know who you are.

Django can store session data in different places, configured in `settings.py`:

  • `SESSION_ENGINE`:
    - `'django.contrib.sessions.backends.db'`: (Default) Stores sessions in the database. Good and persistent.
    - `'django.contrib.sessions.backends.cache'`: Stores sessions in your cache (e.g., Redis). Faster, but not persistent (users are logged out if cache is cleared).
    - `'django.contrib.sessions.backends.signed_cookies'`: Stores all session data *inside* the cookie itself (encrypted). Fast, but cookies have a size limit.
# A simple view showing how sessions are used
def my_view(request):
    # Get a 'visit_count' from the session,
    # default to 0 if it doesn't exist
    visit_count = request.session.get('visit_count', 0)
    
    # Increment the count
    visit_count += 1
    
    # Save it back into the session
    request.session['visit_count'] = visit_count
    
    # This count will persist for this user
    return HttpResponse(f"You have visited this page {visit_count} times.")

19. What is the Django caching framework?

The caching framework is a system for saving the results of expensive operations so you don't have to compute them over and over.

Analogy: The Chef's Hot Plate
Imagine a chef (`View`) has to prepare a very complex sauce (an expensive `SELECT` query).

  • Without Cache: Every time a waiter asks for the sauce, the chef makes it from scratch. This is slow and wastes resources.
  • With Cache: The chef makes the sauce once, puts it on a "hot plate" (the cache, like Redis or Memcached), and sets a 10-minute timer.
  • For the next 10 minutes, any waiter who asks gets the sauce instantly from the hot plate. The database is never bothered.
  • After 10 minutes, the cache "expires," and the next request will cause the chef to make a fresh batch.

Django provides a robust, simple-to-use API for caching. You just need to configure your `CACHES` backend in `settings.py`.

# settings.py
# Example configuration for using Redis as the cache
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }
}

# my_app/views.py
from django.core.cache import cache

def my_expensive_view(request):
    # 1. Try to get the data from the cache
    report = cache.get('my_daily_report')
    
    # 2. If it's not in the cache...
    if report is None:
        # 3. ...run the expensive query
        report = run_very_slow_database_query()
        
        # 4. Save the result in the cache for 15 mins
        cache.set('my_daily_report', report, 60 * 15)
        
    return render(request, 'my_report.html', {'report': report})

20. Difference between view-level caching and template-level caching.

These are two common strategies for applying the caching framework.

View-Level Caching

This is the "all-or-nothing" approach. You cache the entire response from a view.

Analogy: The chef puts the entire, fully-plated dish (the whole HTML page) on the hot plate.

  • How: Use the `@cache_page` decorator.
  • Use Case: Perfect for pages that are identical for all users, like a homepage, a blog post, or a product listing.
from django.views.decorators.cache import cache_page

# This entire view's response will be
# cached for 15 minutes.
@cache_page(60 * 15)
def homepage_view(request):
    # ... logic to get blog posts ...
    return render(request, 'index.html', context)

Template-Level (Fragment) Caching

This is a more granular approach. You cache just one specific, heavy part of a template.

Analogy: The page is customized ("Welcome, Alice!"), but the "Top 10 Products" sidebar is the same for everyone. The chef makes the custom part of the meal but grabs the sidebar from a pre-made batch.

  • How: Use the {% cache %} template tag.
  • Use Case: Perfect for dynamic pages that have common "heavy" components. This gives you the best mix of customization and performance.
{% load cache %}

<h1>Welcome, {{ user.username }}!</h1>

<div class="sidebar">
    {% cache 500 sidebar %}
        <h3>Top 10 Products</h3>
        <ul>
            {% for product in top_products %}
                <li>{{ product.name }}</li>
            {% endfor %}
        </ul>
    {% endcache %}
</div>
🚀 Deep Dive With AI Scholar