Подавить "? next = blah" поведение в django's login_required decorator

18

Я люблю django @login_required decorator, но есть одна вещь, которую я не могу понять, как это сделать.

Если пользователь, не прошедший проверку подлинности, пытается посещать страницу @login_required (например, «/ private-stuff /»), я хочу отбросить их на домашнюю страницу (например, «/ home /»). Но я не хочу добавлять аргумент «? Next =» к URL-адресу. Другими словами, я просто хочу перенаправить на «/ home /», а не «/ home /? Next = / private-stuff /".

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

    
задан Abe 08.06.2012 в 16:06
источник

3 ответа

7

Ну, есть два способа, о которых я могу думать. Во-первых, это был бы «правильный» способ, в том смысле, что вы не нарушаете никаких функциональных возможностей, добавляя только новые функции: создайте свой собственный login_required decorator. Проблема состоит в том, что Django имеет действительно перенаправляет перенаправление после входа в систему и требует много частей. login_required decorator на самом деле просто обертка вокруг user_passes_test decorator , который, в свою очередь, вызывает redirect_to_login view , и это , что , которое добавляет next param для строки запроса. В вашем обычном декораторе вы можете перевернуть все или некоторые из этих функций прямо в декоратор, но вам нужно будет ссылаться на все три для необходимого кода.

Другим и более простым вариантом является создание некоторого промежуточного программного обеспечения для удаления запроса, если он установлен:

from django.conf import settings
from django.http import HttpResponseRedirect

class RemoveNextMiddleware(object):
    def process_request(self, request):
        if request.path == settings.LOGIN_URL and request.GET.has_key('next'):
            return HttpResponseRedirect(settings.LOGIN_URL)

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

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

ответ дан Chris Pratt 08.06.2012 в 16:50
источник
  • has_key устарел. Вместо этого используйте «in». –  Patrick Bassut 06.04.2014 в 07:51
  • @PatrickBassut он не устарел, он полностью удален в Python 3. Я обновил ответ, чтобы быть совместимым с python3. Python 2 устарел, мне интересно, почему люди все еще используют его в 2017 году. –  Helga Iliashenko 23.02.2017 в 13:08
35

Не просто ли это:

@decorators.login_required(redirect_field_name=None)
    
ответ дан Danosaure 07.10.2012 в 00:35
источник
  • Вы на самом деле пытались это сделать? Это было несколько месяцев назад, но я думаю, что я попробовал redirect_url = None, и это не сработало. –  Abe 07.10.2012 в 05:08
  • Да, я попробовал его с текущей версией Django. Обратите внимание, что параметр redirect_field_name, а не redirect_url. –  Danosaure 09.10.2012 в 01:43
  • Является ли эта часть стандартной функциональностью @login_required? Я не могу найти ссылки на это в django docs docs.djangoproject.com/en/1.5/topics/auth/default/... –  bab 30.06.2013 в 07:05
  • Подпись - login_required ([redirect_field_name = REDIRECT_FIELD_NAME, login_url = None]), так что в этом вопрос? –  Danosaure 01.07.2013 в 21:42
  • не будет ли это @login_required (redirect_field_name = None), то? docs.djangoproject.com/en/1.5/topics/auth/default/... ... И это не обязательно будет работать во всех местах. Например, @method_decorator предназначен для принятия себя как аргумента и может работать в разных сценариях ... stackoverflow.com/questions/9560840/... –  nicorellius 09.02.2014 в 06:19
Показать остальные комментарии
0
login(request, user)
if request.POST['next']:
    return redirect(request.POST['next'])
else:
    msg = u"Welcome..."
    return render_to_response('members/welcome.html', {'msg':msg},
                                              context_instance=RequestContext(request))
    
ответ дан electrocoder 01.06.2014 в 18:29
источник
  • Лучше всего добавить контекст, чтобы объяснить свой ответ, а не только чистый код. Это делает его более полезным не только для этого вопросника, но и для всех, кто может иметь такую ​​же проблему и в будущем. См. Эти рекомендации о том, как написать хороший ответ для получения дополнительной информации :) –  starsplusplus 01.06.2014 в 18:48