Получение связанного класса модели из auth.models.User - PullRequest
0 голосов
/ 18 марта 2011

Я работаю над приложением, у которого есть три типа профиля.Каждая из этих моделей имеет внешний ключ к пользовательской модели contrib.auth.models.

Я хотел бы иметь единый вход для каждого типа модели и обеспечить перенаправление через метод класса в зависимости от того, какая модель профиляtype относится к зарегистрированному пользователю.

Вот некоторый псевдокод, иллюстрирующий то, что я хотел бы сделать:

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 для этого?или мне лучше просто написать преобразователь классов, который зацикливается на массиве "профильных" классов?Я не вижу, как я могу сделать это с ContentTypes из класса User, если кто-то не знает обходной путь.

Заранее спасибо, Брэндон

1 Ответ

1 голос
/ 18 марта 2011

[РЕШИТЬ] Итак, в итоге я создал модель соединения 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)

Затем я сделал сигнал предварительного сохранения, чтобы запустить 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, и получитьURL-адрес для перенаправления из метода класса after_login_redirect () для этого типа контента.:)

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 User.Я надеюсь, что это поможет кому-то.Если бы я мог улучшить это, я бы хотел услышать некоторые идеи.

Спасибо, Брэндон

...