20

Dec

Filed in Code, Curse, Django, How-To's |

One issue I’ve personally had to overcome with Django, and languages which aren’t specifically designed for the web, is that you don’t have access to the environment everywhere. The environment I’m referring to, is the current request, and response objects.

In PHP there is no response object, at least not one as you would see in Django. If you wish to set a header or cookie, you simply do it (before output has been given). In .NET it’s more or less the same, you set it in a globally accessible environment variable. This makes it very easy for random tidbits of code to modify the headers.

We were recently implementing our new authentication service on Curse. The authentication service, of course, has to set several cookies. The issue we had to overcome was the authentication service may not, and usually wouldn’t, have access to a response object, as it hadn’t been created yet. The solution we came up with was simply to make the request.COOKIES variable have set methods on it.

The code itself is fairly confusing, as I attempted to override request.COOKIES originally with just a Cookie() object. This proved to be a backwards-compatible issue as it wouldn’t return a string by default with getitem (you would need to call cookie.value to get it’s value instead). To ensure backwards compatibility we had to subclass the Cookie, and Morsel methods, and override getitem to act the same.

All in all, we ended up with two middleware pieces, and a new class for request.COOKIES. The prehandler middleware should be your first middleware, and the post should be your last.

You can view the source at PasteThat.

View Comments Responses to "Set cookies without a response in Django"

Subscribe to this topic with RSS or get the Trackback URL
Bruce (Feb 10th):

David, would you mind if we used this code in Satchmo? (http://satchmoproject.com)

What attribution should we give you, if so?

Jordi Rivero (Mar 5th):

great code, very useful!

Leave A Reply

 Username (*required)

 Email Address (*private)

 Website (*optional)

Note: Comments moderation may be active so there is no need to resubmit your comment.
blog comments powered by Disqus