Django: есть ли способ избежать запросов на request.user при каждом запросе? - PullRequest
9 голосов
/ 11 мая 2011

Для моего веб-сайта почти каждая страница имеет строку заголовка с надписью «Добро пожаловать, ABC», где «ABC» - это имя пользователя. Это означает, что request.user будет вызываться для каждого отдельного запроса, что приводит к повторному обращению к базе данных.

Но как только пользователь войдет в систему, я смогу сохранить его экземпляр user в его файле cookie и зашифровать его. Таким образом, я могу избежать повторного попадания в базу данных и просто получить request.user из cookie.

Как бы вы изменили Django для этого? Есть ли плагины Django, которые делают то, что мне нужно?

Спасибо

Ответы [ 4 ]

4 голосов
/ 11 мая 2011

Это пахнет чрезмерной оптимизацией. Получение пользователя из базы данных - это одно попадание на запрос или, возможно, два, если вы также используете модель профиля. Если ваш сайт таков, что дополнительные два запроса сильно влияют на производительность, у вас могут быть большие проблемы.

4 голосов
/ 11 мая 2011

Вы хотите использовать промежуточное программное обеспечение сеанса и прочитать документацию .Промежуточное программное обеспечение сеанса поддерживает несколько механизмов сеансов .В идеале вы должны использовать memcached или redis, но вы можете написать свой собственный движок сессий для хранения всех данных в cookie пользователя .Как только вы включите промежуточное программное обеспечение, оно станет частью объекта запроса.Вы взаимодействуете с request.session, который действует как диктат, облегчая использование.Вот несколько примеров из документов:

Это упрощенное представление устанавливает переменную has_commented в True после того, как пользователь оставит комментарий.Это не позволяет пользователю оставлять комментарии более одного раза:

def post_comment(request, new_comment):
    if request.session.get('has_commented', False):
        return HttpResponse("You've already commented.")
    c = comments.Comment(comment=new_comment)
    c.save()
    request.session['has_commented'] = True
    return HttpResponse('Thanks for your comment!')

Это упрощенное представление регистрирует «участника» сайта:

def login(request):
    m = Member.objects.get(username=request.POST['username'])
    if m.password == request.POST['password']:
        request.session['member_id'] = m.id
        return HttpResponse("You're logged in.")
    else:
        return HttpResponse("Your username and password didn't match.")
2 голосов
/ 11 мая 2011

Пользователь присоединяется к объекту запроса с использованием промежуточного программного обеспечения аутентификации, предоставленного django (django.contrib.auth.middleware).Он использует функцию get_user в django.contrib.auth. init , чтобы получить пользователя из используемого вами бэкэнда.Вы можете легко изменить эту функцию, чтобы искать пользователя в другом месте (например, cookie).

Когда пользователь вошел в систему, django помещает идентификатор пользователя в сеанс (request.session [SESSION_KEY] = user.id).Когда пользователь выходит из системы, он удаляет идентификатор пользователя из сеанса.Вы можете переопределить эти функции входа в систему и выхода из системы, чтобы также сохранить объект пользователя в браузере. Cookie / удалить объект пользователя из файла cookie в браузере.Обе эти функции также находятся в django.contrib.auth. init

См. Здесь, чтобы настроить файлы cookie: Файлы cookie Django, как их установить?

1 голос
/ 11 мая 2011

После того, как вы правильно кешируете, количество попаданий в базу данных должно быть значительно уменьшено - опять же, я не особо разбираюсь в кешировании.Я думаю, что было бы плохой идеей изменить request.user для решения вашей проблемы.Я думаю, что лучшим решением было бы создание некоторой утилиты, метода или пользовательского тега шаблона, который пытается загрузить требуемые пользовательские данные из файла cookie и вернуть результат.Если пользовательские данные не найдены в файле cookie, необходимо выполнить запрос к request.user, сохранить данные в файле cookie и вернуть результат.Возможно, вы могли бы использовать сигнал post_save для проверки изменений в пользовательских данных, чтобы вы могли обновлять cookie по мере необходимости.

...