代码之家  ›  专栏  ›  技术社区  ›  cethegeek

如何将request.user转换为proxy auth.user类?

  •  17
  • cethegeek  · 技术社区  · 14 年前

    我也有同样的难题 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 回复  |  直到 10 年前
        1
  •  16
  •   Daniel Roseman    14 年前

    这是另一个数据库点击,但这将起作用:

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

    编辑 你可以试试:

    o = OrderedUser()
    o.__dict__ = request.user.__dict__
    
        2
  •  14
  •   FlyDanoFly    10 年前

    我无法让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...
    ]