This is a very good use case for django.contrib.auth.signals.user_login_failed
signal - was introduced in Django 1.5, it is sent when the user failed to login successfully:
from django.contrib.auth import signals
def listener_login_failed(sender, credentials, **kwargs):
# handle log in failure
signals.user_login_failed.connect(listener_login_failed)
Also see tests for django.contrib.auth.signals
.