Right now, the Django cache system doesn't cache pages that have GET
parameters. This is because GET parameters don't necessarily influence
the output of the page. For example, if the page example.com/foo/ is
cached, anybody could simply add a "?bar=baz" to the URL and Django
wouldn't know whether that was a separate page, or just a bunch of
bogus query string cruft added by a nincompoop. So that's why Django
currently doesn't cache any pages with GET parameters, across the
board.

This is a bad long-term solution, though.

I have a couple of ideas for solutions. The first is to introduce a
NO_GET_PARAMS setting, which would default to False. If it's set to
True, Django would assume that *all* GET parameters (query strings),
sitewide, contain meaningless information, and therefore would not
account for them in creating cache. For example, a request to
example.com/foo/?bar=baz would use the same cache as example.com/foo/.
We might even be able to reuse this setting for other things; I'm not
sure what, yet.

Another solution could be to introduce a view decorator that specifies
the view doesn't care about GET parameters. Essentially it'd be the
opposite of the vary_on_headers decorator
(http://www.djangoproject.com/documentation/cache/#controlling-cache-using-vary-headers).
However, it'd a hassle to have to add that decorator to each view,
particularly if you're like me and rarely query strings.

Finally, along those lines, we could introduce a vary_on_get
decorator, which, used with the NO_GET_PARAMS setting, would be an
opt-in signifying a view *does* rely on query string. This could be
for stuff like search engines, which do vary based on the query string
(e.g. /search/?q=foo). In this case, though, it'd be nice to be able
to specify the variables that are valid. For example, with the
decorator @vary_on_get('foo', 'bar'), the cache would store separate
pages for /search/?foo=1 and /search/?bar=1, but it would use the same
cache for /search/?foo=1 and /search/?foo=1&gonzo=2, because "gonzo"
isn't specified in "vary_on_get" and thus would be ignored.

What do people think of these ideas?

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

Reply via email to