Реализация функционала "Войти как" в админке django

Прежде всего необходимо написать функцию, которая позволит администратору входить под любым аккаунтом. Основная загвоздка в том, что функция авторизации в джанго login требует наличия аттрибута backend у объекта пользователя, который обычно присваивается в функции authenticate, но так как мы не знаем пользовательского пароля, данный с пособ нам не подходит.

Для обхода данного ограничения присвоим пользователю первый попавшийся backend из списка settings.AUTHENTICATION_BACKENDS

В данной реализации функция позволяет войти только суперпользователям, но легко переписать это поведение под свои нужды.

Все функции описаны внутри класса UserAdmin, т.к. все равно в нашем случае доступ к ним нужен только из админки.

 

from django.contrib.auth import login, load_backend
def login_as(self, request, pk):
    if not request.user.is_superuser:
        return HttpResponseForbidden()
    user = get_object_or_404(User.objects.active(), pk=pk)

    if not hasattr(user, 'backend'):
        for backend in settings.AUTHENTICATION_BACKENDS:
            if user == load_backend(backend).get_user(user.pk):
                user.backend = backend
                break
    login(request, user)
    return redirect('/')

 

Далее нам нужна ссылка по которой мы сможем перейти для авторизации, мы отобразим ее сразу в списке list_display, т.к. это проще и не нужно лишний раз заходить на страницу пользователя. Выглядеть в админке будет примерно так:

 

 

Ссылку мы сделаем иконкой, чтобы выглядела красивее.

Теперь сама функция возвращающая ссылку.

 

def login_as_link(self, obj):
    if not obj.is_active:
        return ''
    return '<a href="{}"><img src="/static/images/icon_home_a.gif"></a>'\
           .format(reverse('admin:login_as', kwargs={'pk': obj.pk}))
login_as_link.short_description = _('Login as')
login_as_link.allow_tags = True

 

Не забудем добавить ее list_display:

 

list_display = ('email', 'username', 'company', 'country', 'region',\
                'is_active', 'login_as_link', 'view_on_site')

 

Осталось сконфигурировать urls для функции login_as:

 

def get_urls(self):
    urls = super(UserAdmin, self).get_urls()
    login_as_url = patterns('',
                            url(r'^login_as/(?P<pk>\d+)/$',
                                self.admin_site.admin_view(self.login_as), name='login_as')
                            )
    return login_as_url + urls

 

Объединяем все вместе и поставленная задача решена.

Благодарим за внимание и надеемся, что данный материал съэкономит кому-нибудь немного времени, которое можно будет потратить на изучение django.

 

Ещё статьи

Завершена работа над сайтом компании "Хороший мастер"
Завершена работа над сайтом детской футбольной школы «Чемпион»
Обзор django-cms 3.0
Django orm съедает память