Michael Wehner
Michael Wehner

Reputation: 763

How to manipulate the response object in django-piston?

I have some existing python code that uses django-piston which returns a dictionary as its response. For example:

from piston.handler import BaseHandler

class FooHandler(BaseHandler):
    allowed_methods = ('GET',)

    @classmethod
    def create(self, request):
        return { 'foo': 'bar' }

This code works fine, and is serialized into JSON with the appropriate HTTP header set (I'm assuming this works by some piston magic involving emitters; for bonus points, feel free to clarify how this behavior works as well, as I'm still getting to know django-piston).

I need to be able to modify the response in arbitrary ways, e.g. setting headers, status codes, etc. without using some pre-baked solution designed for a specific purpose. Is there a convenient way to access the response object in the context of this code and manipulate it, or has the response object not yet been created? In order to get access to a response object, will I have to construct it manually (a la vanilla django), serialize the dictionary, and set the appropriate headers by hand, and thus lose out on some of the useful magic of django-piston?

Upvotes: 3

Views: 2244

Answers (3)

sock
sock

Reputation: 1054

It is possible to set a custom response code by returning an HttpResponse object from your handler methods.

return HttpResponse({'foo': 'bar'}, status=404)

Unfortunately, you cannot set headers in the same way. For this, you have to write a custom Emitter that sets the headers you need. Something along these lines might work:

class CustomEmitter(JSONEmitter):
    def render(self, request):
        content = super(CustomEmitter, self).render(request)
        response = HttpResponse(content)
        response['Cache-Control'] = 'max-age=60'

Emitter.register('json', CustomEmitter, 'application/json; charset=utf-8')

Upvotes: 1

Josh Smeaton
Josh Smeaton

Reputation: 48730

You are quite right that django-piston uses emitters to serialize/deserialize requests and responses. You can even register your own emitters with piston and have it use those.

There are several ways that you can determine what the format should be.

1. mime-type
2. <format> in your URL
3. .json at the end of your URL

Which particular headers are you wanting to manipulate? There may be other solutions then just hacking away at the response object.

Upvotes: 0

M. Ryan
M. Ryan

Reputation: 7192

Every django-piston method returns an HTTPResponse.

When you return that dictionary, django-piston is just serializing it and sticking it in an HTTPResponse that it has crafted of some variety.

Kind of surprised you didn't pick up on that given that those "return rc.CREATED" lines in all the django-piston examples in the wiki are just hyper-simplistic responses with an HTTP code and response body.

Take a look here: https://bitbucket.org/jespern/django-piston/src/c4b2d21db51a/piston/utils.py

at the rc_factory class, which creates a variety of simple HTTPResponse objects for use with Piston.

At the very least you can observe how they do it, and then craft your own.

But the answer to the essence of your question "can I make a custom HTTPResponse" is yes, you can. Of course, that's what web servers do.

Upvotes: 1

Related Questions