在活塞处理程序中,我需要返回django.db.models.query.QuerySet作为适当的JSON消息(反映底层模型和查询),同时还要添加我自己的HttpResponse标头。到目前为止,我可以做一个或另一个,但不能两者都做(并获得适当外观的JSON响应)。
以下代码会生成正确的JSON格式的响应,但未添加HttpResponse标头(未显示):
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
结果格式正确的JSON消息:
[
{
"pub_date": "2010-08-23 22:15:07",
"question": "What's up?",
"id": 1
}
]
下面的代码使用添加的标头实现了HttpResponse并生成了一个JSONish的响应,但这不是期望或想要的响应,并且没有反映django的“DateTimeAwareJSONEncoder”所做的任何事情(由活塞的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
结果格式错误的JSONish消息:
[
{
"pk": 1,
"model": "polls.poll",
"fields": {
"pub_date": "2010-08-23 22:15:07",
"question": "What's up?"
}
}
]
毫无疑问,这是发生的,因为我正在做自己的JSON序列化,绕过了活塞的JSONEmitter,因此做了一切正确呈现“post”的事情。
我一直在注视着活塞的epitters.py,在很大程度上无法跟上它(我在OOP / Python / django / piston还是很新的)。如何获得活塞来传递格式正确的JSON消息,以及带有我提供的标头的HTTP标头?
最佳答案
您可以继承piston.resource.Resource
的子类,并在__call__
方法中添加所需的任何标头。
从piston.resource导入资源
class MyResource(Resource):
def __call__(self, request, *args, **kwargs):
resp = super(MyResource, self).__call__(request, *args, **kwargs)
resp['HEADER'] = "abc123"
return resp
然后,在您的urls.py中:
def BasicResource(handler):
return resource.MyResource(handler=handler, authentication=basic)
your_handler = BasicResource(YourHandlerClass)
another_handler = BasicResource(AnotherHandlerClass)