Подтвердить что ты не робот

Как преобразовать request.user в прокси-сервер auth.User?

У меня такая же головоломка, как представленная в этом вопросе, но применимая к 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), но это дополнительный удар по базе данных.

Итак, как преобразовать базовый класс модели в свой прокси-класс?

4b9b3361

Ответ 1

Это другая база данных, но это будет работать:

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

Изменить. Вы можете попробовать:

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

Ответ 2

Я не мог заставить метод copy dict работать с Python 2.7.4 и Django 1.6. Я не проследил все это вниз, но я думаю, что это связано с тем, что это ленивый объект.

Что сработало для меня:

request.user.__class__ = OrderedUser

Он избегает вызова базы данных и предоставляет доступ к базовому файлу auth и всем моим расширенным поведением.

Чтобы заставить 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...
]