在本地化页面中删除缓存的问题

Posted

技术标签:

【中文标题】在本地化页面中删除缓存的问题【英文标题】: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 " 
                      >
            % 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 " 
                              >&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 "   >
                    % 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>

【问题讨论】:

你能展示一下你是如何设置语言的吗? 添加了用于更改相关语言的表单 【参考方案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 设置?

以上是关于在本地化页面中删除缓存的问题的主要内容,如果未能解决你的问题,请参考以下文章

H5 localstorage本地缓存数据的封装以及在vue中的使用

有没有一种简单的方法可以从本地 gradle 缓存中删除一个依赖项?

记Git保存本地密码与删除本地缓存

如何从本地 cocoapods 缓存中清除或清理特定的 pod

Flutter——FadeInImage本地缓存图片

如何避免本地 Web 应用程序数据被删除?