web-dev-qa-db-ja.com

Django:一部のページでは、WSGIRequestオブジェクトに属性 'user'がありませんか?

ユーザーがログインしているかどうかにかかわらず、Cookieを設定したい。

私のミドルウェア:

class UserStatus(object):
    def process_response(self,request,response):
        user_status = 1 if request.user.is_authenticated() else 0
        max_age = (20)*52*7*24*60*60 # 20 years (After expiry, cookie gets deleted)
        response.set_cookie(user_status_cookie,user_status,max_age)
        return response

に追加 MIDDLEWARE_CLASSES最後にsettings.pyで。

問題:

  • エラー:「WSGIRequest」オブジェクトに属性「ユーザー」がありません
  • なぜ、認証ミドルウェアとセッションミドルウェアがすでにアクティブになっているのですか?
  • また、一部のページはこのエラーが発生しているため、スムーズに機能しています。
  • 何が悪いのですか?
18
Yugal Jindle

FineManualによると:

応答フェーズ(process_response()およびprocess_exception()ミドルウェア)の間、クラスは下から上に逆の順序で適用されます

したがって、ミドルウェアを追加した方がよいと思いますbefore認証ミドルウェアとセッションミドルウェア(応答のみを処理する場合)。

これが言われている、私はあなたがいくつかのページでのみエラーを持っているという事実に少し困惑しています???

12

最近同じ問題に遭遇し、末尾のスラッシュなしでURLにアクセスしていて、APPEND_SLASH設定がtrueに設定されているときに発生することがわかりました。


Djangoが最初のリクエストを処理する

  • CommonMiddleware.process_request
    • 末尾にスラッシュがあるnewurlにリダイレクトします
  • process_responseは引き続きカスタムミドルウェアで実行されます
    • request.userが存在しません
  • HTTP 301

Djangoは、スラッシュを付けてURLのリクエストを処理します

  • process_responseはカスタムミドルウェアで実行されます
    • request.userが存在します

永続的なリダイレクトの後で、いくつかの主な属性(ユーザーとセッション)がprocess_responseでアクセスできない理由を誰かが知っていますか?

25
YacineAzmi

つまり、Django Common Middlewareによるリダイレクトを介して_APPEND_SLASH_が適用され、AuthenticationMiddlewareuser属性を追加)のprocess_request()が実行されないようにする必要がありますが、_process_response_まだ実行中です。

Djangoプロセスミドルウェアが実際に機能する方法を次に示します(Django 1.6の_Django/core/handlers/base.py_から)

  1. 末尾にスラッシュがないURLをリクエストしました。つまり_yourdomain.com/view_です。これにより、ミドルウェアフローが開始されます。
  2. リクエストがCommonMiddlewareに到達すると、ミドルウェアはスラッシュがないことを確認し、http.HttpResponsePermanentRedirect(newurl)を返します。これにより、AuthenticationMiddleware属性をuserに追加するrequestの1つを含め、追加の_process_requests_の実行が直ちに停止されます
  3. CommonMiddlewareが例外(_Http404_を含む)を返さなかったため、Djangoはミドルウェアから応答を受け取り、_MIDDLEWARE_CLASSES_にリストされているすべてのミドルウェアのEVERY process_response()を介して実行します。そのミドルウェアのprocess_request()を実行する機会があった場合。

これを修正する唯一の実際の方法は、_MIDDLEWARE_CLASSES_のAuthenticationMiddlewareの後にあるprocess_request()メソッドにコードを移動するか、requestオブジェクトにuser属性があるかどうかをhasattr()を介して検出することです。

16
NickCatal

このミドルウェアはアクティブですか?:

'Django.contrib.auth.middleware.AuthenticationMiddleware'

そして、このミドルウェアはミドルウェアの前に実行されますか?

9
Goin

同様の問題があり、一部のページではリクエストにユーザーが含まれていないため、ミドルウェアでは簡単なチェックを行います

if not hasattr(request, 'user'):
    return response
4
sidarcy

DjangoのAuthenticationMiddleware(リクエストオブジェクトへの.userの割り当てを担当する)の前に実行されるミドルウェアまたはその他のコード内で例外が発生する可能性があります。

次に、.user変数にアクセスするとAttributeErrorが発生します。

たとえば、AuthenticationMiddlewareを実行する前に例外がトリガーされると、エラービューが実行される可能性があります。エラービューがrequest.userに依存している場合、質問のタイトルに記載されているエラーが表示されます。

0
Evgeny