web-dev-qa-db-ja.com

Djangoカスタムミドルウェアクラスからrest_framework.responseオブジェクトを返す方法は?

ユーザーがログインしていることを確認するミドルウェアクラスを作成しようとしています。ただし、問題は、このミドルウェアクラスは少数のビューにのみ適用され、これらのビューはDRFのResponseオブジェクトではなく、 HTTPResponseオブジェクトとこれらのビューもapi_viewを使用して装飾されています。

したがって、ミドルウェアクラスからResponseオブジェクトを返そうとすると、このエラーが発生します。

 assert renderer, ".accepted_renderer not set on Response"
AssertionError: .accepted_renderer not set on Response

SOで少し検索しましたが、エラーはapi_viewデコレータに何らかの形で関連していると思います。しかし、この問題の解決方法に困惑しています。

どんな助けでもありがたいです。 :)

28
Adil Malik

最近この問題に遭遇しました。このソリューションはDjango Rest Framework Responseを使用していませんが、サーバーがJSONを返すだけの場合、このソリューションはうまくいくかもしれません。

Django 1.7の新機能は、JSONResponse応答タイプです。

https://docs.djangoproject.com/en/1.7/ref/request-response/#jsonresponse-objects

ミドルウェアでは、「受け入れられていないレンダラー」エラーや「レスポンスに属性エンコードがありません」エラーがまったく発生せずに、これらのレスポンスを返すことができます。

DRF応答と非常によく似た形式です。

インポートは次のとおりです:_from Django.http import JsonResponse_

そしてそれをどのように使うか:

return JsonResponse({'error': 'Some error'}, status=401)

うまくいけば、これはあなたを助けるでしょう!

23
Jordan

残りのフレームワークビューが_accepted_renderer_、_accepted_media_type_、および_renderer_context_を使用して応答オブジェクトにパッチを適用する方法を模倣することで、これを自分で解決しました。私の場合、部分的にはself.client.get(...)を呼び出して_response.data_をアサートしたときにテストがRESTフレームワークの応答を期待しているため、Rest Frameworks Responseクラスを使用して401応答を返したかっただけです。

他の使用例では、_renderer_context_に追加情報を提供するか、別の_accepted_renderer_を使用する必要がある場合があります。

_from rest_framework import status
from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response

class MiddlewareClass(object):

    def __init__(self, get_response):
        self.get_response = get_response

    def unauthorized_response(self, request):
        response = Response(
            {"detail": "This action is not authorized"},
            content_type="application/json",
            status=status.HTTP_401_UNAUTHORIZED,
        )
        response.accepted_renderer = JSONRenderer()
        response.accepted_media_type = "application/json"
        response.renderer_context = {}

        return response

    def __call__(self, request: HttpRequest):
        if not self.authorized(request):
            return self.unauthorized_response(request)
        return self.get_response(request)
_
8
A. J. Parr