I18N and caching: page don't change language until I press F5 in browser

208 views
Skip to first unread message

Salvatore Iovene

unread,
Nov 4, 2011, 11:31:46 AM11/4/11
to django...@googlegroups.com
Hi,
I've got a Django website that's multi-lingual, and I'd like to use memcaching on it. While everything works fine with caching disabled, I have observed the following when caching is enabled:

1) Open any page on the website
2) Click on link (the image of a little flat) to change language
3) This runs a view that sets the language in the session and the cookie, and then redirects to the referrer
4) Observe that the page is still in the original language!
5) Press F5 in the browser
6) Observe that the page is now in the language I wanted

Obviously I'm expecting the page to change language at point 4 (and that's the way it works without caching.

Now let me how you some relevant code:

My middlewares:

MIDDLEWARE_CLASSES = (                                                                                         
    'django.middleware.cache.UpdateCacheMiddleware', # KEEP AT THE BEGINNING                                   
    'django.middleware.http.ConditionalGetMiddleware',                                                         
    'django.middleware.common.CommonMiddleware',                                                               
    'django.contrib.sessions.middleware.SessionMiddleware',                                                    
    'django.contrib.auth.middleware.AuthenticationMiddleware',                                                 
    'django.middleware.cache.CacheMiddleware',                                                                 
    'django.middleware.locale.LocaleMiddleware',                                                                                                                     
    'django.contrib.messages.middleware.MessageMiddleware',                                                                                                         
    'privatebeta.middleware.PrivateBetaMiddleware',                                                            
    'django.middleware.cache.FetchFromCacheMiddleware', # KEEP AT THE END                                      


The view that changes language:

@require_GET
def set_language(request, lang):
    from django.utils.translation import check_for_language, activate

    next = request.REQUEST.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/'
    response = HttpResponseRedirect(next)
    if lang and check_for_language(lang):
        if hasattr(request, 'session'):
            request.session['django_language'] = lang
        else:
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
        activate(lang)

    if request.user.is_authenticated():
        profile = UserProfile.objects.get(user = request.user)
        profile.language = lang
        profile.save()

    return response


I have tried changing the order of the middleware, but to no avail.

Can somebody please help?

Thanks!
  Salvatore.

Salvatore Iovene

unread,
Nov 4, 2011, 11:32:44 AM11/4/11
to django...@googlegroups.com
PS: I have also tried the @vary_on_header('Accept-Language') decorator, but unfortunately that didn't help either.

Salvatore Iovene

unread,
Nov 4, 2011, 2:12:57 PM11/4/11
to django...@googlegroups.com
On Friday, November 4, 2011 5:31:46 PM UTC+2, Salvatore Iovene wrote:
        if hasattr(request, 'session'):
            request.session['django_language'] = lang
        else:
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)

I have solved my problem by setting the cookie unconditionally (i.e. outside of that else-statement). I copied that code from django.views.i18n.set_language. I wonder if that's a bug. 

Torsten Bronger

unread,
Nov 5, 2011, 1:43:33 AM11/5/11
to django...@googlegroups.com
Hall�chen!

Salvatore Iovene writes:

Strange. I had the very same problem, but I identified the
browser's internal caching heuristics as the problem. If there are
no explicit caching headers in the response, the browser guesses.
Sending e.g. "Expires: ..." so that the page expires immediately
solved the problem.

(By the way, I didn't send those headers eventually. The browser's
heuristics make the site faster in other cases, and users switch
language only seldomly.)

Tsch�,
Torsten.

--
Torsten Bronger Jabber ID: torsten...@jabber.rwth-aachen.de
or http://bronger-jmp.appspot.com

Salvatore Iovene

unread,
Nov 5, 2011, 3:27:31 AM11/5/11
to django...@googlegroups.com
On Sat, Nov 5, 2011 at 7:43 AM, Torsten Bronger
<bro...@physik.rwth-aachen.de> wrote:
> Sending e.g. "Expires: ..." so that the page expires immediately
> solved the problem.

Sending an Expires header so that the page expires immediately does
work, but it feels like fixing a headache with a guillotine. The
browser should cache it's own version whenever possible, even though
we're caching server side with memcached.

--
Salvatore Iovene
http://www.google.com/profiles/salvatore.iovene

Torsten Bronger

unread,
Nov 5, 2011, 10:10:30 AM11/5/11
to django...@googlegroups.com
Hall�chen!

Salvatore Iovene writes:

> On Sat, Nov 5, 2011 at 7:43 AM, Torsten Bronger
> <bro...@physik.rwth-aachen.de> wrote:
>
>> Sending e.g. "Expires: ..." so that the page expires immediately
>> solved the problem.
>
> Sending an Expires header so that the page expires immediately
> does work, but it feels like fixing a headache with a
> guillotine. The browser should cache it's own version whenever
> possible, even though we're caching server side with memcached.

See
<http://www-archive.mozilla.org/projects/netlib/http/http-caching-faq.html>.
Other browsers have similar rules. If you don't tell the browser
explicitly not to cache the page, it might just do this -- and so
won't ask the server. Then, re-coding your web app won't help.

Reply all
Reply to author
Forward
0 new messages