Meine app versucht, die django.contrib.auth.views Login und Logout Ansichten mit einigen grundlegenden Auditing/Protokollierung Fähigkeiten zu wickeln. Ich folge dem Rezept wie beschrieben in der django-axes Projekt, und in der Ausführung auf einem Server und einige andere Tests, es funktioniert wie erwartet, transparent ohne Problem.
Der Code lautet wie folgt:
from django.contrib.auth import views as auth_views
from myapp.watchers import watch_login
class WatcherMiddleware(object):
def __init__(self):
auth_views.login = watch_login(auth_views.login)
Und
def watch_login(func):
def decorated_login(request, *args, **kwargs):
#do some stuff
response = func(request, *args, **kwargs)
#more stuff
return response
return decorated_login
Urls:
#Edit: Added project's urls - just using vanilla django's auth login
(r'^accounts/login/$', 'django.contrib.auth.views.login',{"template_name":settings.LOGIN_TEMPLATE }),
In unserem Build-Workflow stoßen wir jedoch auf einige Probleme in der django.contrib.auth.tests.views.
Konkret sind dies die Tests, die in django.contrib.auth fehlschlagen:
ERROR: test_current_site_in_context_after_login (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 192, in test_current_site_in_context_after_login
response = self.client.get(reverse('django.contrib.auth.views.login'))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
*args, **kwargs)))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
"arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.
======================================================================
ERROR: test_security_check (django.contrib.auth.tests.views.LoginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Python26\lib\site-packages\django\contrib\auth\tests\views.py", line 204, in test_security_check
login_url = reverse('django.contrib.auth.views.login')
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 351, in reverse
*args, **kwargs)))
File "C:\Python26\lib\site-packages\django\core\urlresolvers.py", line 297, in reverse
"arguments '%s' not found." % (lookup_view_s, args, kwargs))
NoReverseMatch: Reverse for 'myapp.watchers.decorated_login' with arguments '()' and keyword arguments '{}' not found.
Nur diese beiden Tests schlagen fehl, wenn der "Wrapped Login Monkey"-Patch verwendet wird.
Es scheint, als ob der reverse()-Aufruf im django auth-Test sich anders verhält als eine ungepatchte Funktion, die ihr Ding macht.
Der Grund, warum wir diesen Weg für das Wrapping Logging im Gegensatz zu den neuen Authentifizierungssignalen von Django 1.3 gehen, ist, dass die dort vorgesehene Logging-Methode Sie nur informiert, wenn ein falscher Versuch passiert - sie gibt Ihnen keinen Zugriff auf das Request-Objekt, um zusätzliche Informationen über die unzulässige Anfrage zu protokollieren. Parcheando das Authentifizierungsformular wäre in diesem Fall nicht hilfreich gewesen, daher die Notwendigkeit, die Login-Funktion zu verpacken.
Mache ich etwas falsch, wenn ich die Anmeldefunktion umschreibe? Oder ist dies wie zu erwarten, mit Tests fehlschlagen aufgrund von anderen Nebenwirkungen, trotz keine Änderung in der Gesamtfunktionalität?
edit: Ich benutze Python 2.6.4, Django 1.2.5