Как установить HTTP-заголовок для сообщения JSON из обработчика django-pneon? - PullRequest
3 голосов
/ 07 сентября 2010

В обработчике поршня мне нужно вернуть 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, но тот, который не соответствует ожидаемому или желаемому, плюс не отражает того, что делает DateTimeAwareJSONEncoder django (используется поршневым 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'.

Я поливал поршень emitters.py и почти не могу им следовать (я довольно новичок в OOP / Python / django / piston). Как я могу заставить поршень доставить правильно отформатированное сообщение JSON с заголовком HTTP, дополненным указанными мной заголовками?

1 Ответ

3 голосов
/ 28 января 2011

Вы можете создать подкласс piston.resource.Resource и добавить любой заголовок в методе __call__. из поршня.ресурс импорт ресурса

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)
...