Fixed #7220 -- Allowed AbstractBaseUser.last_login to be null.
Thanks veena for the suggestion and Simon Charette and Kévin Etienne for reviews.
This commit is contained in:
parent
1a31d9ef91
commit
a2479f46f3
|
@ -0,0 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auth', '0004_alter_user_username_opts'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='user',
|
||||
name='last_login',
|
||||
field=models.DateTimeField(null=True, verbose_name='last login', blank=True),
|
||||
),
|
||||
]
|
|
@ -172,7 +172,7 @@ class UserManager(BaseUserManager):
|
|||
email = self.normalize_email(email)
|
||||
user = self.model(username=username, email=email,
|
||||
is_staff=is_staff, is_active=True,
|
||||
is_superuser=is_superuser, last_login=now,
|
||||
is_superuser=is_superuser,
|
||||
date_joined=now, **extra_fields)
|
||||
user.set_password(password)
|
||||
user.save(using=self._db)
|
||||
|
@ -190,7 +190,7 @@ class UserManager(BaseUserManager):
|
|||
@python_2_unicode_compatible
|
||||
class AbstractBaseUser(models.Model):
|
||||
password = models.CharField(_('password'), max_length=128)
|
||||
last_login = models.DateTimeField(_('last login'), default=timezone.now)
|
||||
last_login = models.DateTimeField(_('last login'), blank=True, null=True)
|
||||
|
||||
is_active = True
|
||||
|
||||
|
|
|
@ -156,6 +156,13 @@ class AbstractUserTestCase(TestCase):
|
|||
self.assertEqual(message.from_email, "from@domain.com")
|
||||
self.assertEqual(message.to, [abstract_user.email])
|
||||
|
||||
def test_last_login_default(self):
|
||||
user1 = User.objects.create(username='user1')
|
||||
self.assertIsNone(user1.last_login)
|
||||
|
||||
user2 = User.objects.create_user(username='user2')
|
||||
self.assertIsNone(user2.last_login)
|
||||
|
||||
|
||||
class IsActiveTestCase(TestCase):
|
||||
"""
|
||||
|
|
|
@ -56,7 +56,7 @@ class PasswordResetTokenGenerator(object):
|
|||
key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
|
||||
|
||||
# Ensure results are consistent across DB backends
|
||||
login_timestamp = user.last_login.replace(microsecond=0, tzinfo=None)
|
||||
login_timestamp = '' if user.last_login is None else user.last_login.replace(microsecond=0, tzinfo=None)
|
||||
|
||||
value = (six.text_type(user.pk) + user.password +
|
||||
six.text_type(login_timestamp) + six.text_type(timestamp))
|
||||
|
|
|
@ -81,8 +81,12 @@ Fields
|
|||
|
||||
.. attribute:: last_login
|
||||
|
||||
A datetime of the user's last login. Is set to the current date/time by
|
||||
default.
|
||||
A datetime of the user's last login.
|
||||
|
||||
.. versionchanged:: 1.8
|
||||
|
||||
This field will be ``null`` if the user has never logged in.
|
||||
Previously it was set to the current date/time by default.
|
||||
|
||||
.. attribute:: date_joined
|
||||
|
||||
|
|
|
@ -407,6 +407,26 @@ officially supports.
|
|||
This also includes dropping support for PostGIS 1.3 and 1.4 as these versions
|
||||
are not supported on versions of PostgreSQL later than 8.4.
|
||||
|
||||
``AbstractUser.last_login`` allows null values
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The :attr:`AbstractUser.last_login <django.contrib.auth.models.User.last_login>`
|
||||
field now allows null values. Previously, it defaulted to the time when the user
|
||||
was created which was misleading if the user never logged in. Please run the
|
||||
database migration. If your custom user inherits from ``AbstractUser`` and you
|
||||
wish to set ``last_login`` to ``NULL`` for users who haven't logged in, you can
|
||||
run this query::
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import AbstractBaseUser
|
||||
|
||||
UserModel = get_user_model()
|
||||
if issubclass(UserModel, AbstractBaseUser):
|
||||
UserModel._default_manager.filter(
|
||||
last_login=models.F('date_joined')
|
||||
).update(last_login=None)
|
||||
|
||||
Miscellaneous
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
|
Loading…
Reference in New Issue