68

私は次の方法を持っています:

def _attempt(actor):
    if actor.__class__ != User:
        raise TypeError

ビューから呼び出されるもの:

self.object.attempt(self.request.user)

ご覧のとおり、_attempt メソッドはアクターが typedjango.contrib.auth.models.Userであることを期待していますが、オブジェクトは type であるように見えますdjango.utils.functional.SimpleLazyObject。これはなぜですか?LazyObjectさらに重要なことに、 (どうやら User オブジェクトのラッパーのようなものです) をオブジェクトに変換するにはどうすればよいUserでしょうか?

詳細については、 httpsRequest.user : //docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.user を参照してください。このドキュメントは、オブジェクトである必要があることを示しているようです...request.userUser

======事後編集=====

私は今次の方法を持っています:

def _attempt(obj, action, actor, msg): 
    actor.is_authenticated() 
    if isinstance(actor, LazyObject): 
        print type(actor) 

ユーザーを渡していますが、if条件はまだ true であり、アクターはまだLazyObject. これはなぜですか?

4

7 に答える 7

43

同様の質問に対する私の回答を参照してください。

Django の遅延読み込みは、認証状態に応じてorのrequest.userいずれかになります。属性がアクセスされたときにのみ「ウェイクアップ」し、適切なクラスを返します。残念ながら、それはプリミティブ クラスの属性であるため、カウントされません。これが実際には型であることを知る必要がある場合があるため、 orにプロキシするのは間違っています。UserAnonymousUser__class__SimpleLazyObjectUserAnonymousUser

長くても短くても、この比較をそのまま行うことはできません。しかし、あなたは本当にここで何を達成しようとしていますか? UserそれがまたはAnonymousUserであるかどうかを確認しようとしている場合はrequest.user.is_authenticated()、たとえばそのためのものがあります。

ただし、原則として、ダックタイピングを乱用すべきではありません。パラメータは、必ずしもそうである必要はありませんが、常に特定のタイプまたはサブタイプ (またはUser)UserSubClassである必要があります。そうしないと、紛らわしくて脆いコードになってしまいます。

于 2012-07-03T17:00:00.663 に答える
19

これはそれを行う必要があります:

# handle django 1.4 pickling bug
if hasattr(user, '_wrapped') and hasattr(user, '_setup'):
    if user._wrapped.__class__ == object:
        user._setup()
    user = user._wrapped

セッションディクショナリにユーザーを追加できるように、これを作成する必要がありました。(SimpleLazyObjectsは選択できません!)

于 2012-11-09T08:14:44.427 に答える
11
user= request.user._wrapped if hasattr(request.user,'_wrapped') else request.user

次に、userの代わりに使用しますrequest.user

これは UsAaR33 の回答に似ていますが、オブジェクトの変換にはワンライナーの方が適しています。

于 2013-04-30T16:29:14.457 に答える
0

auth_userこれはDjangoのテーブルのスキーマです-

id
password
last_login
is_superuser
username
last_name
email
is_staff
is_active
date_joined
first_name

id今、次のように書きたい場合は-

req.user.id

そして、あなたが次のようにusername書きたいなら-

req.user.username
于 2021-11-13T18:14:31.600 に答える
0

コードを次のように変更すれば問題ありません。

from copy import deepcopy

def _attempt(actor):
    actor = deepcopy(actor)
    if actor.__class__ != User:
        raise TypeError
于 2020-02-22T10:21:38.843 に答える