How to set an HTTP header for a JSON message from within a django-piston handler?
In a piston handler, I need to return a django.db.models.query.QuerySet as a proper JSON message (reflective of the underly model and query), while also adding an HttpResponse header of my own. So far, I can do one or the other, but not both (and get a proper looking JSON response).
The below generates a proper JSON formatted response, but with no added HttpResponse header (not shown):
class PollHandlerSearch(BaseHandler):
allowed_methods = ('POST')
model = Poll
fields = ('id', 'question', 'pub_date')
KEYS = ( 'question', 'start-date', 'end-date' )
def create(self, request):
post = Poll.objects.all()
for skey in self.KEYS:
if len(post) and request.POST.has_key(skey) and len(request.POST[skey]):
if skey == self.KEYS[0]:
post = post.filter(question__icontains=request.POST[skey])
elif skey == self.KEYS[1]:
post = post.filter(pub_date__gte=request.POST[skey])
elif skey == self.KEYS[2]:
post = post.filter(pub_date__lte=request.POST[skey])
return post
Resulting correctly formatted JSON message:
[
{
"pub_date": "2010-08-23 22:15:07",
"question": "What's up?",
"id": 1
}
]
The below implements an HttpResponse with the added header and generates a JSONish looking response, but one that is not what is being expected or wanted, plus not reflecting whatever django's 'DateTimeAwareJSONEncoder' does (used by piston's JSONEmitter).
class PollHandlerSearch(BaseHandler):
allowed_methods = ('POST')
model = Poll
fields = ('id', 'question', 'pub_date')
KEYS = ( 'question', 'start-date', 'end-date' )
def create(self, request):
resp = HttpResponse()
post = Poll.objects.all()
for skey in self.KEYS:
if len(post) and request.POST.has_key(skey) and len(request.POST[skey]):
if skey == self.KEYS[0]:
post = post.filter(question__icontains=request.POST[skey])
elif skey == self.KEYS[1]:
post = post.filter(pub_date__gte=request.POST[skey])
elif skey == self.KEYS[2]:
post = post.filter(pub_date__lte=request.POST[skey])
json_serializer = serializers.get_serializer("json")()
json_serializer.serialize(post, ensure_ascii=False, indent=4, stream=resp)
resp['MYHEADER'] = 'abc123'
return resp
Resulting incorrectly formatted JSONish message:
[
{
"pk": 1,
"model": "polls.poll",
"fields": {
"pub_date": "2010-08-23 22:15:07",
"question": "What's up?"
}
}
]
This is no doubt happening since I am doing my own JSON serialization, bypassing piston's JSONEmitter and thus whatever it does to properly render 'post'.
I have been pouring over piston's emitters.py, and largely can't follow it (I am pretty new at OOP / Python / django / piston). How can I get piston to deliver a properly formatted JSON message开发者_如何学编程 with an HTTP header supplemented with headers I provide?
You could subclass piston.resource.Resource
, and add whatever header you want in the __call__
method.
from piston.resource import Resource
class MyResource(Resource):
def __call__(self, request, *args, **kwargs):
resp = super(MyResource, self).__call__(request, *args, **kwargs)
resp['HEADER'] = "abc123"
return resp
Then, in your urls.py:
def BasicResource(handler):
return resource.MyResource(handler=handler, authentication=basic)
your_handler = BasicResource(YourHandlerClass)
another_handler = BasicResource(AnotherHandlerClass)
精彩评论