Hacking Django Admin, hooks for login/logout

2019-04-08 13:32发布

How do I add hooks to the Django Admin, such that I can execute a function when the user logs in or out?

4条回答
该账号已被封号
2楼-- · 2019-04-08 14:11

Update: This method is obsolete since Django 1.3, see Tommy's answer below for using signals.

I was also looking for an answer to this and ended up going another way. You can use your own views for login and logout, which perform some action and then call the auth views. For login:

def login(request, *args, **kwargs):
    from django.contrib.auth.forms import AuthenticationForm
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            # login successful
            do_something()
    from django.contrib.auth.views import login as authlogin
    return authlogin(request, *args, **kwargs)

And for logout:

def logout(request, *args, **kwargs):
    do_something() 
    from django.contrib.auth.views import logout as authlogout
    return authlogout(request, *args, **kwargs)

You can do whatever processing you like in your custom views in place of the do_something placeholders, such as emitting signals, logging log-in and log-out times, etc.

Finally, don't forget to update your urls.py to point to your custom views.

I'm not sure how a custom auth backend can handle logout events, as i eventually gave up on that and tried this instead. Additionally, this approach has the advantage of making available the request object instead of just the user.

查看更多
老娘就宠你
3楼-- · 2019-04-08 14:15

Django does sadly not send any signals on that events.... But you could make your own custom AuthorizationBackend that enables you to do so:

from django.dispatch import Signal

post_login = Signal(providing_args=['user'])

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User

class AuthSignalBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = User.objects.get(username=username)
            if user.check_password(password):
                post_login.send(sender=None, user=user)
                return user
        except User.DoesNotExist:
            return None


def login_handler(sender, **kwargs):
    print "logging in..."        
post_login.connect(login_handler)

To enable it you have to put AUTHENTICATION_BACKENDS = (myapp.mymodule.AuthSignalBackend',) in your settings.py!

查看更多
聊天终结者
4楼-- · 2019-04-08 14:18

As of Django 1.3, the auth framework does generate signals for login and logout which can be used to provide your own hook.

You have to connect your function to the django.contrib.auth.signals.user_logged_in signal like:

def fun(sender, **kwargs):
     print "do your custom stuff here"

from django.contrib.auth.signals import user_logged_in
user_logged_in.connect(fun)
查看更多
可以哭但决不认输i
5楼-- · 2019-04-08 14:19

I just found this thread when searching for a solution so others might too...

Lazerscience answer looks good so far but I also notice that the Django core devs have accepted a patch that will cause a Signal on log-in/log-out.

This might be a more elegant solution once it makes it into an official Django release.

And for reference, the docs on Signals.

查看更多
登录 后发表回答