last_login field is not updated when authenticating using Tokenauthentication in Django Rest Framework last_login field is not updated when authenticating using Tokenauthentication in Django Rest Framework django django

last_login field is not updated when authenticating using Tokenauthentication in Django Rest Framework


Well, at the end I inherited from the REST Framework TokenAuthentication, pointing to it in the urls file

url(r'^api-token-auth/', back_views.TokenAuthenticationView.as_view()),

and the View handles the request and manually calls the update_last_login like this:

from django.contrib.auth.models import update_last_loginclass TokenAuthenticationView(ObtainAuthToken):    """Implementation of ObtainAuthToken with last_login update"""    def post(self, request):        result = super(TokenAuthenticationView, self).post(request)        try:            request_user, data = requests.get_parameters(request)            user = requests.get_user_by_username(data['username'])            update_last_login(None, user)                    except Exception as exc:            return None        return result


@F.D.F. answer is great. Here is another way of doing it.

We send user_logged_in signals that will call update_last_login:

user_logged_in.send(sender=user.__class__, request=request, user=user)

Here is a working view (based on a custom User model that uses email as USERNAME_FIELD) :

from rest_framework import parsers, renderersfrom rest_framework.authtoken.models import Tokenfrom rest_framework.response import Responsefrom rest_framework.views import APIViewfrom django.contrib.auth.signals import user_logged_infrom emailauth.serializers import AuthTokenSerializer, UserSerializerclass ObtainAuthToken(APIView):    throttle_classes = ()    permission_classes = ()    parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,)    renderer_classes = (renderers.JSONRenderer,)    serializer_class = AuthTokenSerializer    def post(self, request, *args, **kwargs):        serializer = self.serializer_class(data=request.data)        serializer.is_valid(raise_exception=True)        user = serializer.validated_data['user']        token, created = Token.objects.get_or_create(user=user)        user_logged_in.send(sender=user.__class__, request=request, user=user)        return Response({'token': token.key, 'user': UserSerializer(user).data})obtain_auth_token = ObtainAuthToken.as_view()

You can find the full source code here : Api View with last_login updated

Hope this helps.


A cleaner way to do it:

from django.contrib.auth.models import update_last_loginfrom rest_framework.authtoken.models import Tokenfrom rest_framework.authtoken.views import ObtainAuthTokenclass LoginToken(ObtainAuthToken):    def post(self, request, *args, **kwargs):        result = super().post(request, *args, **kwargs)        token = Token.objects.get(key=result.data['token'])        update_last_login(None, token.user)        return result

And then setup urls.py:

url(r'^api-token-auth/', views.LoginToken.as_view()),