对request.user使用代理类而不是User

时间:2012-01-12 21:56:29

标签: django django-models

我有一个Django User模型的元类,我用它来添加额外的方法(过度简化的版本):

# project.models.pie_lover.py

from django.contrib.auth.models import User

class PieLover(User):
    class Meta:
        app_label = "core"
        proxy = True

    def likes_pie(self):
        return True

在我看来,我希望登录PieLover,看看他是否喜欢馅饼(愚蠢的事情要做,因为PieLover总是喜欢馅饼,但在现实世界的情况下,这可能不是是这样的)。我的问题在于Django登录用户的方式,我使用内置的login(request)函数,因此存储在request.user中的对象是User对象,而不是PieLover

# project.views.like_pie.py

from ..models.pie_lover import PieLover

def index(request):
    pie_lover = request.user

    if pie_lover.likes_pie():
        print "Try pie, try!"
    else:
        print "BLASPHEMER!"

如果我尝试这样做,Django会告诉我,User对象没有方法likes_pie,因为request.user不是PieLover实例。< / p>

作为一种快速解决方法,我只需获得与PieLover具有相同ID的User,但这意味着额外的数据库命中。

如何在请求中默认使用Django PieLover? 我想的是,而不是进行另一个数据库查询,以获取正确的PieLover对象来创建一个新的PieLover对象,并在初始化时将request.user传递给它,但我不知道其含义是什么这是。

3 个答案:

答案 0 :(得分:6)

在探索之后,我发现,在我看来,访问给定PieLover实例的User方法的最简单且非hackish的方法。我已将此添加到自定义中间件:

from models.pie_lover import PieLover

class PieLoverMiddleware(object):
    def process_request(self, request):
        request.pie_lover = PieLover(request.user)

答案 1 :(得分:1)

如何在请求中默认使用Django使用PieLover?

  

你没有。

在您执行任何其他操作之前,请先阅读此内容:https://docs.djangoproject.com/en/1.3/topics/auth/#storing-additional-information-about-users

您对用户的“扩展”应该是一个单独的模型,其中包含该单独模型中的所有扩展方法。

然后,您可以使用已提供的get_profile()方法,轻松地从用户(在请求中)导航到您的扩展程序。

答案 2 :(得分:0)

from django.contrib.auth import models as auth_models

def _my_func(self):
    return True

auth_models.User.my_func = _my_func