从auth.models.User获取相关的模型类

时间:2011-03-17 21:20:29

标签: django django-authentication

我正在开发一款具有三种“配置文件”型号的应用。每个模型都有contrib.auth.models用户模型的外键。

我希望每个模型类型都有一个单独的登录,并通过classmethod提供重定向,具体取决于哪个“profile”模型类型与登录用户相关。

这里有一些伪代码来说明我想要做的事情:

from django.contrib.auth import authenticate, login
from django.http import HttpResponse, HttpresponseRedirect

from lib.forms import Loginform #extends the built-in AuthenticationForm

def login_user(request):
    if request.method == 'POST':
        form = LoginForm(data=request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            user = authenticate(username=cleaned_data.get('username'), \
                password=cleaned_data.get('password'))
            if user:
                login(request, user)

                #Determine the content type of the model related to the user
                #get the correct redirect value from an @classmethod
                #called: after_login_redirect for that type and...

                return HttpResponseRedirect(klass.after_login_redirect())
        else:
            response = form.errors_as_json()
            return HttpResponse(json.dumps(response, ensure_ascii=False), \
               mimetype='application/json')

是否可以利用ContentTypes框架来执行此操作?或者我最好只编写一个循环遍历“profile”类数组的类解析器?除非有人知道解决方法,否则我没有看到使用User类中的ContentTypes的方法。

提前致谢, 布兰登

1 个答案:

答案 0 :(得分:1)

<强> [解决]
所以,我最终做的是创建一个如下所示的UserContentType结点模型:

from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType

class UserContentType(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)

然后,如果我拥有的三个“profile”模型之一的实例没有id,我发出了一个预保存信号来触发get或create:

from django.contrib.contenttypes.models import ContentType

from lib.models import UserContentType

def set_content_type_for_user(sender, **kwargs):
    instance = kwargs.get('instance')
    content_type = ContentType.objects.get_for_model(instance)
    user = instance.user
    if not instance.id:
        user_content_type, \
            created = UserContentType.objects.get_or_create(user=user, \
            content_type=content_type, \
            defaults={'user' : user, 'content_type' : content_type})

然后,在我通过ajax发布的自定义登录视图中,我可以获取与User实例关联的内容类型,并从该内容类型的'after_login_redirect()'类方法获取重定向到的URL。 :)

def login_user(request):
    if request.method == 'POST':
        form = LoginForm(data=request.POST)
        if form.is_valid():
            cleaned_data = form.cleaned_data
            user = authenticate(username=cleaned_data.get('username', ''),
                                password=cleaned_data.get('password', ''))
            if user:
                login(request, user)
                user_content_type = UserContentType.objects.get(user=user)
                redirect_path = 
                   user_content_type.content_type.\
                    model_class().after_login_redirect_path()
                response = {'redirect_path' : redirect_path}
        else:
            response = form.errors_as_json()
        return HttpResponse(json.dumps(response, \
            ensure_ascii=False), mimetype='application/json')

这样一来,我就没有monkeypatch用户了。我希望这可以帮助别人。如果有一种方法可以改进,我很乐意听到一些想法。

谢谢, 布兰登