19

ユーザーがログインしているかどうかにかかわらず、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」オブジェクトに属性「user」がありません
  • なぜ、認証ミドルウェアとセッションミドルウェアがすでにアクティブになっているのですか?
  • また、一部のページはスムーズに機能していますが、一部のページではこのエラーが発生しています。
  • 私は何を間違っているのですか?
4

6 に答える 6

25

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


Djangoは最初のリクエストを処理します

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

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

  • process_responseはカスタムミドルウェアで実行されます
    • request.userが存在するようになりました

永続的なリダイレクト後、process_responseで主要な属性(ユーザーとセッション)の一部にアクセスできない理由を知っている人はいますか?

于 2013-02-10T02:11:53.103 に答える
17

したがってAPPEND_SLASH、Django Common Middlewareによるリダイレクトを介して適用され、process_request()in (属性AuthenticationMiddlewareを追加する)が実行されないようにする必要がありますが、まだ実行されています。userprocess_response

Djangoプロセスミドルウェアが実際にどのように機能するかを次に示します(django/core/handlers/base.pyDjango 1.6以降)

  1. 末尾にスラッシュがないURLをリクエストします。だからyourdomain.com/view。これにより、ミドルウェアフローが開始されます。
  2. リクエストがに達するCommonMiddlewareと、ミドルウェアはスラッシュがないことを確認し、を返しますhttp.HttpResponsePermanentRedirect(newurl)。これにより、属性を追加するものprocess_requestsを含め、追加の実行が即座に停止されます。AuthenticationMiddlewareuserrequest
  3. 例外(を含む)CommonMiddlewareを返さなかったため、ミドルウェアからの応答を受け取り、そのミドルウェアが実行される機会があったかどうかに関係なく、にリストされているすべてのミドルウェアのすべてを実行します。Http404djangoprocess_response()MIDDLEWARE_CLASSESprocess_request()

これを修正する唯一の実際の方法は、コードをinのprocess_request()後にあるメソッドに移動するか、オブジェクトに属性があるかどうかをviaで検出することです。AuthenticationMiddlewareMIDDLEWARE_CLASSEShasattr()requestuser

于 2014-01-13T20:42:13.073 に答える
12

FineManualによると:

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

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

そうは言っても、一部のページでしかエラーが発生しないという事実に少し戸惑っています???

于 2012-06-27T10:17:35.693 に答える
9

このミドルウェアをアクティブにしていますか?:

'django.contrib.auth.middleware.AuthenticationMiddleware'

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

于 2012-06-27T10:18:53.657 に答える
4

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

if not hasattr(request, 'user'):
    return response
于 2014-02-10T15:46:10.717 に答える
0

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

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

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

于 2015-11-22T16:27:50.247 に答える