Internationalization and caching not working!

11 views
Skip to first unread message

Beegee

unread,
Dec 23, 2006, 5:28:46 PM12/23/06
to Django users
I build a Dutch and English website: http://www.localpoint.nl. Traffic
to the website is increasing. That is why I am looking at enabling
Django caching.

However, it does not seem to work! I tried different backends. The file
backend for example does not store any files. I also tried memcached.
That seems to be working although I am not able to check the contents
of memcached itself. Is that possible?

But, whenever I switch between the two languages with caching enabled
the results are unpredictable. I get a Dutch page when I should get an
English one and vice versa.

Is there someone who has experience in setting up caching with a Django
website that uses internationalization (i18n)?

Thanks very much for your help.

By the way these are the middleware settings I am using:

# CacheMiddleware settings
#CACHE_BACKEND = "locmem:///"
#CACHE_BACKEND = "file:///var/www/MyDjango-cache/"
CACHE_BACKEND = "memcached://127.0.0.1:11211/"
CACHE_MIDDLEWARE_KEY_PREFIX = 'localpoint_'
CACHE_MIDDLEWARE_SECONDS = 60 * 5

MIDDLEWARE_CLASSES = (
#"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
"django.middleware.http.ConditionalGetMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.gzip.GZipMiddleware",
"django.contrib.csrf.middleware.CsrfMiddleware", #protection agains
cross site scripting.
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.cache.CacheMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.doc.XViewMiddleware",
)

But I also tried this one:

# CacheMiddleware settings
#CACHE_BACKEND = "locmem:///"
#CACHE_BACKEND = "file:///var/www/MyDjango-cache/"
CACHE_BACKEND = "memcached://127.0.0.1:11211/"
CACHE_MIDDLEWARE_KEY_PREFIX = 'localpoint_'
CACHE_MIDDLEWARE_SECONDS = 60 * 5

MIDDLEWARE_CLASSES = (
#"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
"django.middleware.http.ConditionalGetMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.gzip.GZipMiddleware",
"django.contrib.csrf.middleware.CsrfMiddleware", #protection agains
cross site scripting.
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.doc.XViewMiddleware",
"django.middleware.cache.CacheMiddleware",
)

Same result.

Jeremy Dunck

unread,
Dec 23, 2006, 10:23:30 PM12/23/06
to django...@googlegroups.com
On 12/23/06, Beegee <berry.gr...@gmail.com> wrote:
> But, whenever I switch between the two languages with caching enabled
> the results are unpredictable. I get a Dutch page when I should get an
> English one and vice versa.

The cache middleware creates it's keys based on the initial response's
vary header.
You'll need to use vary_on_headers, presumably including Content-Language.
http://www.djangoproject.com/documentation/cache/#using-vary-headers

Beegee

unread,
Dec 26, 2006, 7:26:35 AM12/26/06
to Django users
Jeremy,

Thanks for your response. But, I am using the locale middleware from
Django itself. And it automatically updates the Vary header. See:
django/trunk/django/middleware/locale.py

def process_response(self, request, response):
patch_vary_headers(response, ('Accept-Language',))
response['Content-Language'] = translation.get_language()
translation.deactivate()
return response

And when I do inspect the header response from my application it indeed
looks like this:
Vary: Accept-Language,Cookie,Accept-Encoding

However you did make me think. You suggested that the Vary header
should include Content-Language. If I look at my response header the
Content-Language header looks like: Content-Language: nl and if I
switch to English it looks like: Content-Language: en. Obviously.

Perhaps there is a bug in locale.py. Should:

patch_vary_headers(response, ('Accept-Language',))

perhaps be:

patch_vary_headers(response, ('Content-Language',))

Could it be that simple? I will check. If this is indeed the solution I
will file a bug.

Berry

On 24 dec, 04:23, "Jeremy Dunck" <jdu...@gmail.com> wrote:


> On 12/23/06, Beegee <berry.groenend...@gmail.com> wrote:
>
> > But, whenever I switch between the two languages with caching enabled
> > the results are unpredictable. I get a Dutch page when I should get an

> > English one and vice versa.The cache middleware creates it's keys based on the initial response's

Beegee

unread,
Dec 26, 2006, 7:27:52 AM12/26/06
to Django users
Jeremy,

Thanks for your response. But, I am using the locale middleware from
Django itself. And it automatically updates the Vary header. See:
django/trunk/django/middleware/locale.py

def process_response(self, request, response):
patch_vary_headers(response, ('Accept-Language',))
response['Content-Language'] = translation.get_language()
translation.deactivate()
return response

And when I do inspect the header response from my application it indeed
looks like this:
Vary: Accept-Language,Cookie,Accept-Encoding

However you did make me think. You suggested that the Vary header
should include Content-Language. If I look at my response header the
Content-Language header looks like: Content-Language: nl and if I
switch to English it looks like: Content-Language: en. Obviously.

Perhaps there is a bug in locale.py. Should:

patch_vary_headers(response, ('Accept-Language',))

perhaps be:

patch_vary_headers(response, ('Content-Language',))

Could it be that simple? I will check. If this is indeed the solution I
will file a bug.

Berry

On 24 dec, 04:23, "Jeremy Dunck" <jdu...@gmail.com> wrote:

> On 12/23/06, Beegee <berry.groenend...@gmail.com> wrote:
>
> > But, whenever I switch between the two languages with caching enabled
> > the results are unpredictable. I get a Dutch page when I should get an

> > English one and vice versa.The cache middleware creates it's keys based on the initial response's

Beegee

unread,
Dec 26, 2006, 8:19:45 AM12/26/06
to Django users

> However you did make me think. You suggested that the Vary header
> should include Content-Language. If I look at my response header the
> Content-Language header looks like: Content-Language: nl and if I
> switch to English it looks like: Content-Language: en. Obviously.
>
> Perhaps there is a bug in locale.py. Should:
>
> patch_vary_headers(response, ('Accept-Language',))
>
> perhaps be:
>
> patch_vary_headers(response, ('Content-Language',))
>
> Could it be that simple? I will check. If this is indeed the solution I
> will file a bug.
>

I made the change mentioned above. But, it simply does NOT work!
Whenever I enable global caching I can NOT switch between languages
anymore. Only one page is saved in the cache!

I enabled file based caching. And I would expect two files in the
cache. One for each language. But, what ever I do only one version of
each page is cached! The order in which the caching middleware appears
also does not seem to matter.

How do I get internationalization (i18n) and caching to work together?

Thanks. Berry

Jeremy Dunck

unread,
Dec 26, 2006, 9:28:55 AM12/26/06
to django...@googlegroups.com
On 12/26/06, Beegee <berry.gr...@gmail.com> wrote:
...

> > Perhaps there is a bug in locale.py. Should:
> >
> > patch_vary_headers(response, ('Accept-Language',))
> >
> > perhaps be:
> >
> > patch_vary_headers(response, ('Content-Language',))
...

>
> I made the change mentioned above. But, it simply does NOT work!
> Whenever I enable global caching I can NOT switch between languages
> anymore. Only one page is saved in the cache!

I apologize for mixing you up. The vary header is "the set of
request-header fields that fully determines, while the response is
fresh, whether a cache is permitted to use the response to reply to a
subsequent request without revalidation". (rfc2616, 14.44 Vary)

Which is to say, Accept-Language is the appropriate value to place in
the Vary header, since that is the request-header field we're
interested in varying on, *not* Content-Language.

Even so, have you verified that your browsers are sending
Accept-Language as expected?

Second, are you using mod_python or wsgi? I'm asking because the
headers django.util.cache.learn_cache_key depends on are expected to
be munged into request.META on round-trip. I do see that munging
occurring in django.core.handlers.modpython, but not in
django.core.handlers.wsgi.

I haven't tested that here-- I'm not set up for trunk testing or i18n,
but if you're using wsgi, this may be your bug...

Beegee

unread,
Dec 28, 2006, 5:19:45 AM12/28/06
to Django users
Jeremy,

Thanks for the explanation. I am using mod_python. I will check if my
browser are sending Accept-Language. But, I suspect they do. Because,
whenever caching is disabled swithing between languages works perfect.
If I change for example the language settings in my browser and make
for example Dutch my preferred language then the website
www.localpoint.nl is rendered in Dutch. And if I make English my
preferred language my website is rendered in English. So, the language
settings in my browsers (FF and IE) are correctly handled by the
Django.

But whenever I activate caching language switching is not working
anymore.

Berry

On Dec 26, 3:28 pm, "Jeremy Dunck" <jdu...@gmail.com> wrote:


> On 12/26/06,Beegee<berry.groenend...@gmail.com> wrote:
> ...
>
> > > Perhaps there is a bug in locale.py. Should:
>
> > > patch_vary_headers(response, ('Accept-Language',))
>
> > > perhaps be:
>
> > > patch_vary_headers(response, ('Content-Language',))
> ...
>
> > I made the change mentioned above. But, it simply does NOT work!
> > Whenever I enable global caching I can NOT switch between languages

> > anymore. Only one page is saved in the cache!I apologize for mixing you up. The vary header is "the set of

Beegee

unread,
Dec 28, 2006, 4:27:05 PM12/28/06
to Django users
I am starting to get to understand the problem. I hope. I did the
following test.

My current middleware settings:

MIDDLEWARE_CLASSES = (
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.gzip.GZipMiddleware",
"django.middleware.cache.CacheMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.csrf.middleware.CsrfMiddleware",
"django.middleware.doc.XViewMiddleware",
"django.middleware.http.ConditionalGetMiddleware",
#"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
)

In Firefox I have three languages enables: nl, en-us and en. I hit a
page and I get two cached files. One cache_header and one cache_page.
When I change my language setting in my browser and delete for example
the en language and hit the same page again I get a second cache_page!
Great! If I switch the remaining nl and en-us settings I get a third
cache_page. So, vary on Accept-language is working. I even get the
correct language shown on the pages. So, something is working even with
caching enabled.

I am getting closer to the problem.

I use the set_language redirect view for the user to be able to switch
between languages. This is still NOT working! From the documentation:
"The view expects to be called via the GET method, with a language
parameter set in the query string. If session support is enabled, the
view saves the language choice in the user's session. Otherwise, it
saves the language choice in a django_language cookie."

I have session enabled. So, the cache should use the vary on cookie.
Even if I do not use sessions the language choice is stored in a cookie
and thus the cache should vary on cookie.

Apparently this is not working!

Switching the order of the middelware to:

MIDDLEWARE_CLASSES = (
"django.middleware.cache.CacheMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.gzip.GZipMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.csrf.middleware.CsrfMiddleware",
"django.middleware.doc.XViewMiddleware",
"django.middleware.http.ConditionalGetMiddleware",
#"django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
)

Then the cache_header files show that the cache is also varying on
cookie. I can switch once between Dutch and English using the set
language redirect view. And I got two cache_pages for each page. But, I
can only switch once!

I am almost there. I think. But, it still is not working! Why?

On 28 dec, 11:19, "Beegee" <berry.groenend...@gmail.com> wrote:
> Jeremy,
>
> Thanks for the explanation. I am using mod_python. I will check if my
> browser are sending Accept-Language. But, I suspect they do. Because,
> whenever caching is disabled swithing between languages works perfect.
> If I change for example the language settings in my browser and make

> for example Dutch my preferred language then the websitewww.localpoint.nlis rendered in Dutch. And if I make English my

Reply all
Reply to author
Forward
0 new messages