harvard-lil/perma

Django's built-in "last_login" field on user not being updated

rebeccacremona opened this issue · 4 comments

Since this deployment in 2020, which included our upgrade from Django 1 to Django 2, the "last_login" field, part of Django's AbstractBaseUser model, updated via signal... has not been updated or populated for any user.

I have not yet diagnosed why. Our pre-save signal for Links is working, so it is not the case that all signals are broken.

A few months after that deployment, we added django-axes, so if we want, we can backfill the appropriate value of this field for any user who has logged in since 2020-10-15 16:40.

Okay, this happened during the upgrade to Django 2.1, because of the change introduced to Django by this PR.

It only registers the update_last_login signal if the user model's last_login is an instance of django.db.models.query_utils.DeferredAttribute.

But, we are using Django Model Utils' FieldTracker to track changes made to our user objects' fields.... so, for us,

last_login_field = getattr(get_user_model(), 'last_login', None)

is a model_utils.tracker.DescriptorWrapper, not a django.db.models.query_utils.DeferredAttribute.

Possible fixes:

  • register the signal ourselves
  • exclude last_login from the fields being tracked
  • swap in LIL's custom field-tracking code, which Jack wrote because "those packages can be error-prone in hard-to-diagnose ways", if it works
  • maybe other ideas too

I'll see what seems to be cleanest.

The tracker was added to LinkUser in 0b90830, which added it to every model in the app at the same time. I don't see that we are actually consulting the tracker on LinkUser anywhere and all our tests pass with it removed.

So, I think we can just get rid of it!

Start: 62075 users with no last_login.
Updated last_login for 81324 users.
End: 51772 users with no last_login.