【问题标题】:Problem with deleting cache in localized page在本地化页面中删除缓存的问题
【发布时间】:2021-09-04 11:44:38
【问题描述】:

我有页面可以查看帖子。此外,我还有带有切换语言选项的标题,当我切换语言时,它会在所有页面上更改,但具有缓存的页面除外。只有当我重新启动服务器时,语言才会发生变化。当我更改语言时,我需要了解如何删除缓存。 视图.py:

class DetailPostView(generic.DetailView):

def get(self, request, *args, **kwargs):
    pk = kwargs['pk']

    post = Post.objects.get(pk=pk)
    comments = Comment.objects.filter(post=post)
    form = CommentForm()

    context = {
        "post": post,
        'comments': comments,
        'form': form,
    }
    return render(request, "detail_post.html", context)

def post(self, request, pk):

    post = Post.objects.get(pk=pk)
    comments = Comment.objects.filter(post=post)
    form = CommentForm(request.POST)

    if form.is_valid():
        author = self.check_user_authenticated(request, form)

        comment = Comment(
            author=author,
            body=form.cleaned_data['body'],
            image=form.cleaned_data['image'] if 'image' in form.cleaned_data else None,
            post=post,
            user=request.user if isinstance(request.user, User) else None
        )
        comment.save()

    context = {'post': post, 'comments': comments, 'form': form}
    return render(request, "detail_post.html", context)

def check_user_authenticated(self, request, form):
    if request.user.is_authenticated:
        author = request.user.profile.name
    elif form.cleaned_data['author']:
        author = form.cleaned_data['author']
    else:
        author = 'Anonim'
    return author

模型.py:

class Post(models.Model):
    title = models.CharField(max_length=25)
    body = models.TextField()
    image = models.ImageField(blank=True, upload_to=post_directory_path)
    created_on = models.DateTimeField(auto_now_add=True)
    last_modified = models.DateTimeField(auto_now=True)
    categories = models.ManyToManyField('Category', related_name='posts', blank=True)
    profile = models.ForeignKey('Profile', verbose_name='User',
                                on_delete=models.CASCADE,
                                related_name='profile')

    def __str__(self):
        return self.title


@receiver(post_save, sender=Post, dispatch_uid="clear_cache_post")
def update_post(sender, **kwargs):
    key = make_template_fragment_key('post', [kwargs['instance'].user.id])
    cache.delete(key)

模板(detail_post.html):

{% extends "base.html" %}
{% load i18n %}
{% load cache %}
{% block page_content %}
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% trans "Detail blog" %}</title>
    </head>
    {% cache 500 post request.user.id %}
        <div class="col-md-8 offset-md-2">
            <h1>{{ post.title }}</h1>
            <small>
                {{ post.created_on|date:"d.m.Y H:i:s" }} |&nbsp;
                {% if post.categories.all %}
                    {% trans 'Categories' %} :&nbsp;
                    {% for category in post.categories.all %}
                        <a href="{% url 'list_category' category.name %}">{{ category.name }}</a>&nbsp;
                    {% endfor %}
                {% else %}
                    {% trans "There isn't any category" %}
                {% endif %}
            </small>
            <p>{{ post.body | linebreaks }}</p>
            {% if post.image %}
                <img src="{{ MEDIA_URL }}{{ post.image.url }}" alt=""
                     width="800px" height="800px">
            {% endif %}
            {% if request.user.id == post.profile.id %}
                <form action="/blog/edit/post/{{ post.id }}" method="get">
                    <button class="btn btn-primary" type="submit" data-toggle="collapse"
                            data-target="#collapseExample"
                            aria-expanded="false" aria-controls="collapseExample">{% trans "Edit post" %}
                    </button>
                </form>
            {% endif %}
            <h3>{% trans "Leave a comment" %}: </h3>
            <form action="/blog/{{ post.pk }}/" method="post">
                {% csrf_token %}
                {% if not request.user.is_authenticated %}
                    <div class="form-group">
                        {{ form.author }}
                    </div>
                {% endif %}
                <div class="form-group">
                    {{ form.body }}
                </div>
                <div class="form-group">
                    {% trans "image" %}: {{ form.image }}
                </div>
                <button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>
            </form>
            {% if comments %}
                <h3>{% trans "Comments" %}:</h3>
                {% for comment in comments %}
                    {% if comment.user.profile.avatar %}
                        </div>
                        <img class="col-md-2" src="{{ MEDIA_URL }}{{ comment.user.profile.avatar.url }}" alt=""
                             width="100px" height="100px">&nbsp;&nbsp;
                        <b>{{ comment.author }}</b> {% trans "wrote at" %} {{ comment.created_on|date:"H:i:s d.m.Y" }}
                        <div class="col-md-8 offset-md-2">
                    {% else %}
                        <b>{{ comment.author }}</b> {% trans "wrote at" %} {{ comment.created_on|date:"H:i:s d.m.Y" }}
                    {% endif %}
                    <p>{{ comment.body }}</p>
                    {% if comment.image %}
                        <img src="{{ MEDIA_URL }}{{ comment.image.url }}" alt="" width="30%" height="30%">
                    {% endif %}
                    {% if request.user.profile %}
                        <form action="/blog/edit/comment/{{ comment.id }}" method="get">
                            <button class="btn btn-primary" type="submit" data-toggle="collapse"
                                    data-target="#collapseExample"
                                    aria-expanded="false" aria-controls="collapseExample">{% trans "Edit commentary" %}
                            </button>
                        </form>
                    {% endif %}
                    <hr>
                {% endfor %}
            {% else %}
                <h3>{% trans "There isn't any comment yet" %}</h3>
            {% endif %}
            </div>
    {% endcache %}
{% endblock %}

模板(base.html):

{% load i18n %}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
      integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container">
        <a class="navbar-brand" href="https://github.com/Gleb-bit/">{% trans 'GitHub' %}</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
                aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item active">
                    <a class="nav-link" href="{% url 'list_project' %}">{% trans 'Home' %}</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'list_post' %}">{% trans 'Blog' %}</a>
                </li>
            </ul>
            <ul class="navbar-nav nav-tabs">
                <li class="nav-item mt-2">
                    <form action="{% url 'set_language' %}" method="post">
                        {% csrf_token %}
                        <input name="text" type="hidden" value="{{ redirect_to }}">
                        <select name="language">
                            {% get_current_language as LANGUAGE_CODE %}
                            {% get_available_languages as LANGUAGES %}
                            {% get_language_info_list for LANGUAGES as languages %}
                            {% for language in languages %}
                                <option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %}
                                        selected {% endif %}>
                                    {{ language.name_local }} ({{ language.code }})
                                </option>
                            {% endfor %}
                        </select>
                        <button class="btn-primary" type="submit">{% trans 'Go' %}</button>
                    </form>
                </li>
                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                       aria-expanded="false" href="#">{% trans 'More' %}</a>
                    <div class="dropdown-menu">
                        {% if request.user.is_authenticated %}
                            <a class="dropdown-item"
                               href="/blog/user/{{ request.user.id }}">{% trans 'Detail account' %}</a>
                            <a class="dropdown-item" href="{% url 'logout' %}">{% trans 'Logout' %}</a>
                        {% else %}
                            <a class="dropdown-item" href="{% url 'login' %}">{% trans 'Login' %}</a>
                        {% endif %}
                    </div>
                </li>
            </ul>
        </div>
    </div>

</nav>

<div class="container">
    {% block page_content %}{% endblock %}
</div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
        integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
        integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
        crossorigin="anonymous"></script>

语言转换表格:

<form action="{% url 'set_language' %}" method="post">
                    {% csrf_token %}
                    <input name="text" type="hidden" value="{{ redirect_to }}">
                    <select name="language">
                        {% get_current_language as LANGUAGE_CODE %}
                        {% get_available_languages as LANGUAGES %}
                        {% get_language_info_list for LANGUAGES as languages %}
                        {% for language in languages %}
                            <option value="{{ language.code }}" {% if language.code == LANGUAGE_CODE %}
                                    selected {% endif %}>
                                {{ language.name_local }} ({{ language.code }})
                            </option>
                        {% endfor %}
                    </select>
                    <button class="btn-primary" type="submit">{% trans 'Go' %}</button>
                </form>

【问题讨论】:

  • 你能展示一下你是如何设置语言的吗?
  • 添加了用于更改相关语言的表单

标签: python html django caching django-cache


【解决方案1】:

根据Template fragment caching for caches using the cache 模板标签的文档,您可以将当前语言作为参数传递给模板标签,以便它随语言而变化,因此您可以编写以下内容:

{% get_current_language as LANGUAGE_CODE %}

{% cache 500 post request.user.id LANGUAGE_CODE %}
    <div class="col-md-8 offset-md-2">
        ...
    </div>
{% endcache %}

对于已缓存的视图,您可以使用文档Using Vary headers 部分中所述的vary_on_headers 装饰器来更改Accept-Language 标头:

from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_headers


@cache_page(500)
@vary_on_headers('Accept-Language')
def some_view(request):
    ...

【讨论】:

  • 即我需要这样做:@cache_page(500) @vary_on_headers('Accept-Language') class Detail Post View(generic.DetailView): pass 以及以后如何删除缓存?
  • @Steep27 不,您似乎正在使用cache 模板标签,该视图代码只是一个示例,以防您缓存完整的视图。你需要使用{% cache 500 post request.user.id LANGUAGE_CODE %},就像我展示的那样,它会在语言上变化(你不需要删除缓存)。
  • 除了模板中的代码({% cache 500 post request.user.id LANGUAGE_CODE %} {% for language in languages %} {% endfor %} {% endcache %}),我还需要添加什么?
  • @Steep27 您需要将LANGUAGE_CODE 传递给您使用的所有cache 模板标签,如果您希望它们在语言上有所不同。我认为您没有在表单中使用标签,为什么要在评论中显示它?在示例中,您使用了detail_post.html 中的标签,我在答案中添加了一个截断版本以反映相同的...
  • 或者您是否使用“每站点缓存”,即您已将缓存中间件添加到MIDDLEWARE 设置?
猜你喜欢
  • 2011-05-16
  • 1970-01-01
  • 2011-01-30
  • 2018-11-08
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 2015-01-12
  • 2012-02-10
相关资源
最近更新 更多