Выход Django не работает

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

мой немного страннее, он работает в google chrome.... но не в Firefox...

это моя функция выхода из системы: (in views.py)

def my_logout(request):
    logger.debug("Logout called by user")
    try:
        # Here I do some custom stuff, like logging this action in a database and so on
        # For this question it shouldn't matter... because in a try catch
        # so whatever goes wrong here, logging out should work anyway
    except Exception, e:
        logger.info("Logging logout action error: %s" % e)
    logout(request)
    return HttpResponseRedirect("/")

in settings.py у меня:

LOGIN_URL = '/desktop/login/'
LOGOUT_URL = '/desktop/logout/'
LOGIN_REDIRECT_URL = '/'

и в urls.py из приложения iamapps (включить в проект urls как / desktop/):

url(r'^login/$', 'iamapps.views.my_login', name='iamapps.login'),
url(r'^logout/$', 'iamapps.views.my_logout', name='iamapps.logout'),

далее info:

  • django 1.4.3 (только что обновлено с 1.3 до 1.4 ....)
  • python 2.7
  • работает в Chrome, но не в Firefox 17.0.1, Linux

тот факт, что он работает в google chrome, но не работает в firefox, озадачивает меня больше всего. Кажется, это имеет какое-то отношение к firefox продолжает помнить, что пользователь вошел в систему...

EDIT: У меня сломана труба.... но я, кажется, понимаю это не на logging из... но сейчас, после выхода....

Traceback (most recent call last):
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
    self.finish_response()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 127, in finish_response
    self.write(data)
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 210, in write
    self.send_headers()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 268, in send_headers
    self.send_preamble()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 192, in send_preamble
    'Date: %srn' % format_date_time(time.time())
  File "/usr/lib/python2.7/socket.py", line 324, in write
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 58684)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 582, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 323, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/media/storage/django/sites/iamfloraservice/parts/django/django/core/servers/basehttp.py", line 139, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 641, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 694, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
[24/Dec/2012 14:33:25] "GET / HTTP/1.1" 200 48247

Изменить 2 он переходит к этому представлению после выхода из системы и перенаправления:

def home(request, template='iamfloraservice/home.html'):

    logger.debug("Home view called by user %s" % request.user)
    return render_to_response(template,{},context_instance=RequestContext(request))

Я думаю, что перенаправление с запросом на это представление вызывает проблему.... В журнале sais это все еще пользователь "michel" (beacuse представление использует запрос из перенаправления, и у этого был пользователь michel)... однако... пользователь michel выходит из системы в то же время....

изменить 3

из-за предложения это связано с регистратором. unremarking ведение журнала не помогает И это регистратор по умолчанию:

import logging
logger = logging.getLogger(__name__)

правка 4 (30-12-2012)

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

Я думаю, что проблема в том, что он перезагружает это главное окно, пока кэш и пользователь в его запросе еще не очищены. Каким-то образом Chrome знает, как справиться с этим, и firefox приводит к ошибке сломанной трубы. Очистка кэша вручную в браузере приводит к правильному представлению после перезагрузки....

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

эта проблема описывается, может быть тот же... но я не могу ожидать, что пользователи будут делать что-либо в браузере только для выхода из системы? см.Django 1.4 кэширование GET to / login/

изменить 5 (31-12-2012)

кажется, это проблема кэширования.... но пока не знаю, как это исправить.

Мои настройки кэширования:

if not DEBUG:
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }
else:
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
        }
    }

но я пробовал без dummycache, а также

редактировать 6 (4-янв-2013) Все еще нет решения.... Я изменил как я выхожу на путь django, и теперь я использую сигналы... см. мой собственный ответ ниже.

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

при входе с помощью интерфейса администратора, поэтому сигнал работает нормально...

Я проверил, выключив сигнал.... и все же выход из системы в firefox не работает.

вывод: возврат к главной странице () вызывает проблему.

редактировать 7 (4 января 2013 года) Я сделал простой вид loggedout для тестирования, этот шаблон:

<html>
<head>
<title>
Logged out
</title>
</head>
<body>
You are succesfully logged out.<br>
<br>
<a href="/">Go back to the main page</a>
or<br>
<a href="/desktop/login/?next=/">log in again</a>
</body>
</html>

и выход из системы:

class LoggedOutView(TemplateView):
    template_name = "iamapps/logged_out.html"

и изменил URL-адреса в кому:

url(r'^logout/$', 'django.contrib.auth.views.logout',  {'next_page': '/desktop/loggedout/'}, name='iamapps.logout'),
#url(r'^logout/$', 'django.contrib.auth.views.logout_then_login',  name='iamapps.logout'),
url(r'^loggedout/$', LoggedOutView.as_view(),name='iamapps.loggedout'),

и все-таки simplyfy вещи... Я отключил все сигналы.

и он все еще не работает в firefox.... но он работает в chrome

в firefox он не переходит на страницу выхода из системы

4 ответов


Я обычно просто использую внесенное представление для выхода из системы пользователей. Просто добавьте это в свой root :

# Would be nice to use settings.LOGIN_URL for `next_page` here, too
url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/login'}),

и вы будете хорошо идти.

Счастливый Djangoing.


Я подозреваю, что исходное представление выхода возвращает ответ, который очищает cookie или что-то в этом роде, и вы выбрасываете этот ответ. Не могли бы вы попробовать просто вернуть свой ответ пользователю, как это?

def my_logout(request):
    # something...
    return logout(request)

просмотр в stackoverflow... (сделал еще один поиск)

Я нашел это: .... см.Джанго.ВНО.автор.выход из системы в Django ..

но это еще хуже.... Я нашел это... восхищенный... но все объясняет: Django, Logout_URL не перенаправляет хорошо

я узнал, что это не исправит ошибку (@##$%%) не разрешено ругаться в канун Рождества....

таким образом, решение сделать мои пользовательские вещи находится в сигналах вместо использовать мой собственный взгляд. Выполните просмотр по умолчанию и перенаправление... и использовать эту документацию для создания сигнала.. https://docs.djangoproject.com/en/dev/topics/auth/#login-and-logout-signals

добавление сигналов довольно легко, я положил его в models.py off my main app (iamapps):

import logging
from django.contrib.auth.signals import user_logged_out
from django.contrib.auth.signals import user_logged_in
logger = logging.getLogger(__name__)

def iam_logged_out_actions(sender, user, request, **kwargs):
    #whatever...
    logger.debug("Logging out: user = %s" % user)

user_logged_out.connect(iam_logged_out_actions)

def iam_logged_in_actions(sender, user, request, **kwargs):
    #whatever...
    logger.debug("Logging in: user = %s" % user)

user_logged_in.connect(iam_logged_in_actions)

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

для выхода из системы я использую сейчас это urls.py:

    url(r'^logout/$', 'django.contrib.auth.views.logout',  {'next_page': '/'}, name='iamapps.logout'),

наконец, я полностью переключился почти обратно на Django по умолчанию... Использование:

in views.py:

from django.contrib.auth.forms import AuthenticationForm
from django.views.generic.edit import FormView

class LoginView(FormView):
    """
    This is a class based version of django.contrib.auth.views.login.


    """
    form_class = AuthenticationForm
    redirect_field_name = REDIRECT_FIELD_NAME
    template_name = 'iamapps/login.html'


    @method_decorator(csrf_protect)
    @method_decorator(never_cache)
    def dispatch(self, *args, **kwargs):
        return super(LoginView, self).dispatch(*args, **kwargs)

    def form_valid(self, form):
        """
        The user has provided valid credentials (this was checked in AuthenticationForm.is_valid()). So now we
        can check the test cookie stuff and log him in.
        """
        self.check_and_delete_test_cookie()
        login(self.request, form.get_user())
        return super(LoginView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super(LoginView, self).get_context_data(**kwargs)
        apps_settings=iamapps_settings()
        if apps_settings[LOGON_BASE_APP_NAME]:
            self.extend_template="%s/base.html" % apps_settings[LOGON_BASE_APP_NAME]
        else:
            self.extend_template="iamapps/base.html"
        context['extend_template']=self.extend_template
        return context    

    def form_invalid(self, form):
        """
        The user has provided invalid credentials (this was checked in AuthenticationForm.is_valid()). So now we
        set the test cookie again and re-render the form with errors.
        """
        self.set_test_cookie()
        return super(LoginView, self).form_invalid(form)

    def get_success_url(self):
        if self.success_url:
            redirect_to = self.success_url
        else:
            redirect_to = self.request.REQUEST.get(self.redirect_field_name, '')

        netloc = urlparse.urlparse(redirect_to)[1]
        if not redirect_to:
            redirect_to = settings.LOGIN_REDIRECT_URL
        # Security check -- don't allow redirection to a different host.
        elif netloc and netloc != self.request.get_host():
            redirect_to = settings.LOGIN_REDIRECT_URL
        return redirect_to

    def set_test_cookie(self):
        self.request.session.set_test_cookie()

    def check_and_delete_test_cookie(self):
        if self.request.session.test_cookie_worked():
            self.request.session.delete_test_cookie()
            return True
        return False

    def get(self, request, *args, **kwargs):
        """
        Same as django.views.generic.edit.ProcessFormView.get(), but adds test cookie stuff
        """
        self.set_test_cookie()
        return super(LoginView, self).get(request, *args, **kwargs)

и urls:

url(r'^login/$', LoginView.as_view(), name='login'),

это решило все мои проблемы... о Логгин и logiing на...

сигналы входа и выхода из системы работают нормально:

from django.contrib.auth.signals import user_logged_out, user_logged_in

# Note, these login and logout signals are registered in imamstats views
def iam_logged_out_actions(sender, user, request, **kwargs):
    try:
        # ... do my logging out actiosn (stats etc.)
    except Exception, e:
        logger.error("Logging logout action error: %s" % e)

# Note, these login and logout signals are registered in imamstats views
def iam_logged_in_actions(sender, user, request, **kwargs):
    try:
        # ... do my log in stats etc. things
    except Exception, e:
        logger.error("Logging login action error: %s" % e)