【问题标题】:How to convert request.user into a proxy auth.User class?如何将 request.user 转换为代理 auth.User 类?
【发布时间】:2010-06-09 14:26:16
【问题描述】:

我和presented in this question 有同样的困惑,但适用于 Django 的 auth.User。

我有这个代理模型:

class OrderedUser(User):
    def __unicode__(self):
        return self.get_full_name()

    class Meta: 
        proxy=True
        ordering=["first_name", "last_name"]

我的一些其他模型使用OrderedUser 而不是django.contrib.auth.models.User 作为字段类型。

在我看来,然后我使用request.user 填充一个字段并 - 正如预期的那样 - 得到一个错误:

'Cannot assign "<User...>": <field> must be a "OrderedUser" instance'

我可以只做OrderedUser.objects.get(request.user.id),但这对数据库来说是一个额外的打击。

那么,如何将基础模型类转换为其代理类?

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    这是另一个数据库命中,但这会起作用:

    OrderedUser.objects.get(pk=request.user.pk)
    

    编辑你可以试试:

    o = OrderedUser()
    o.__dict__ = request.user.__dict__
    

    【讨论】:

    • 对。有没有不涉及到数据库的机制?
    • 感谢您的提示。我发现的一件事是,当在 context_processor 中使用 this 将用户对象传递给模板时......如果用户未登录,您需要以不同的方式执行此操作。正如您所拥有的那样,o 总是以一个 OrderedUser 对象(从 User 继承),但如果用户没有登录,它应该是 AnonymousUser 类型。所以我会测试request.user.is_authenticated() 是否是这样,然后才执行上述操作。否则,请o = request.user
    【解决方案2】:

    我无法让 copy dict 方法在 Python 2.7.4 和 Django 1.6 上工作。我没有一直追踪它,但我认为这与它是一个惰性对象有关。

    什么对我有用:

    request.user.__class__ = OrderedUser
    

    它避免了数据库调用,并允许访问基本身份验证内容和我的所有扩展行为。

    为了使 request.user 始终像代理类一样,我将分配放在中间件中身份验证中间件之后,我的任何应用程序都可以引用它之前。由于每个请求都会调用中间件,因此请确保在设置类之前对用户进行身份验证。使用您的示例,中间件代码如下所示:

    from yourapp.models import OrderedUser
    
    class OrderedUserMiddleware():
        def process_request(self, request):
            if hasattr(request, 'user') and request.user.is_authenticated():
                request.user.__class__ = OrderedUser
    

    并且记得在认证后注册中间件:

    MIDDLEWARE_CLASSES = [
        # ...middleware from the guts of Django, none of your middle wares yet...
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        # ...more middleware from the guts of Django, none of your middlewares yet...
        'yourapp.middleware.OrderedUserMiddleware',
        # ...more middleware from you other middlewares...
    ]
    

    【讨论】:

    • 正是我要找的东西。
    • 这很好用,除了我无法让中间件与 django-rest-framework 身份验证一起工作,不得不求助于设置 class
    猜你喜欢
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2018-09-12
    • 2021-12-24
    • 2019-07-20
    • 2018-07-27
    相关资源
    最近更新 更多