如何将request.user转换为代理auth.User类?

时间:2010-06-09 14:26:17

标签: django django-models

我和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),但这对数据库来说是一个额外的打击。

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

2 个答案:

答案 0 :(得分:16)

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

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

修改您可以尝试:

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

答案 1 :(得分:14)

我无法使用复制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...
]