1

My base.html template, which is extended in nearly all of my pages, contains a header that I never want to be cached since it contains the username of the current user. I have two pages where it keeps getting cached though.

I tried adding a {% cache 0 base request.user.username %} for the header, but to no avail.

I don't want to have to add a @never_cache since I want to keep most of the DOM cached. Is there a way to add a never_cache decorator/functionality to my extended base.html only?

settings.py:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

(Simplified) Base template:

<!doctype html>
<html lang="en">
    <head>
    ...
    </head>
    <body>
        {% block content %}
        {% endblock content %}
        {% block postman_menu %}
        {% endblock postman_menu %}

        {% cache 0 base request.user.username %}
        <header>
            <nav class="nav">
                {% if user.is_authenticated %}
                    <ul class="styled-list">
                        <li>Home</li>
                        <li>Browse</li>
                        <li>Inbox</li>
                        <li>Activity</li>
                        <li>{{ request.user.username }}</li>
                    </ul>
                {% else %}
                    <ul class="styled-list">
                        <li>Home</li>
                        <li>About</li>
                        <li>Log In</li>
                        <li>Sign up</li>
                    </ul>
                {% endif %}
            </nav>
        </header>
        {% endcache %}
    </body>
</html>

I don't have a view defined for my base template, but one of the pages that is giving me problems by caching my header is my browse page, which is defined below.

Views.py:

@login_required(login_url='login')
def browse(request):
    block_list = None
    user_list = None
    post_list = None
    neighbor_list = None
    main_blocks = Block.objects.filter(name__in=current_blocks).order_by('-date_created')
    user = request.user
    query = request.GET.get("q")
    if query:
        block_list = Block.objects.filter(Q(name__icontains=query) | Q(tags__slug__icontains=query)).distinct()
        neighbor_list = user.neighbors.filter(Q(first_name__icontains=query) | Q(last_name__icontains=query) | Q(username__icontains=query)).distinct()
        user_list = CustomUser.objects.filter(Q(first_name__icontains=query) | Q(last_name__icontains=query) | Q(username__icontains=query)).distinct() 
        post_list = Post.objects.filter(Q(tags__slug__icontains=query) | Q(title__icontains=query)).distinct().order_by('-published')
    if neighbor_list and user_list:
        user_list = neighbor_list | user_list
    context = {'block_list': block_list, 'user_list': user_list, 'post_list': post_list, 'main_blocks': main_blocks}
    return render(request, 'browse.html', context)

(Simplified) Browse Template:

{% extends 'base.html' %}
{% load static %}{% load cache %}
{% block title %} Browse {% endblock title %}

{% block content %}
<div class="browse go-left">
    {% cache 300 browseSearch request.user.username %}
    <div class="search-bar-container">
        <form action="" id="browse-form" method="get">
            <div class="search-line">
                <input type="text" name="q" aria-label="Search" placeholder="Search blocks, users, and posts" class="search-bar" value="{{ request.GET.q }}">
            </div>
            <button type="submit" value="Search">Search</button>
        </form>
    </div>
    {% endcache %}

    {% if request.GET.q is not None %}

    ...code to display search results...

    {% else %}

    {% cache 300 browseIntro request.user.username %}

    ...code to display blocks...

    {% endcache %}

    {% endif %}   

</div>
{% endblock content %}
thean
  • 97
  • 9
  • If it contains data then this means that a view output (render) is cached, not a template. Please show corresponding template part and the view as well as settings related to the template engine. – Ivan Starostin Apr 13 '20 at 08:59
  • Just edited my question -- hopefully it's enough information. Let me know if more is needed. Thank you. – thean Apr 13 '20 at 14:16
  • How do you notice that it is cached? – Ivan Starostin Apr 13 '20 at 15:53
  • If I create two users, I log into one and everything works normally. But when I log into another user, in the header the wrong username appears i.e. the username of the last login I used, but not the current one. – thean Apr 13 '20 at 16:12

1 Answers1

1

Take a look at this package, it has an interesting tag nocache that enable you to exclude a subset of a cached template

rachid el kedmiri
  • 2,376
  • 2
  • 18
  • 40