Kaydet (Commit) a2479f46 authored tarafından Tim Graham's avatar Tim Graham

Fixed #7220 -- Allowed AbstractBaseUser.last_login to be null.

Thanks veena for the suggestion and Simon Charette and Kévin Etienne for reviews.
üst 1a31d9ef
# -*- 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): ...@@ -172,7 +172,7 @@ class UserManager(BaseUserManager):
email = self.normalize_email(email) email = self.normalize_email(email)
user = self.model(username=username, email=email, user = self.model(username=username, email=email,
is_staff=is_staff, is_active=True, is_staff=is_staff, is_active=True,
is_superuser=is_superuser, last_login=now, is_superuser=is_superuser,
date_joined=now, **extra_fields) date_joined=now, **extra_fields)
user.set_password(password) user.set_password(password)
user.save(using=self._db) user.save(using=self._db)
...@@ -190,7 +190,7 @@ class UserManager(BaseUserManager): ...@@ -190,7 +190,7 @@ class UserManager(BaseUserManager):
@python_2_unicode_compatible @python_2_unicode_compatible
class AbstractBaseUser(models.Model): class AbstractBaseUser(models.Model):
password = models.CharField(_('password'), max_length=128) 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 is_active = True
......
...@@ -156,6 +156,13 @@ class AbstractUserTestCase(TestCase): ...@@ -156,6 +156,13 @@ class AbstractUserTestCase(TestCase):
self.assertEqual(message.from_email, "from@domain.com") self.assertEqual(message.from_email, "from@domain.com")
self.assertEqual(message.to, [abstract_user.email]) 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): class IsActiveTestCase(TestCase):
""" """
......
...@@ -56,7 +56,7 @@ class PasswordResetTokenGenerator(object): ...@@ -56,7 +56,7 @@ class PasswordResetTokenGenerator(object):
key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator" key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
# Ensure results are consistent across DB backends # 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 + value = (six.text_type(user.pk) + user.password +
six.text_type(login_timestamp) + six.text_type(timestamp)) six.text_type(login_timestamp) + six.text_type(timestamp))
......
...@@ -81,8 +81,12 @@ Fields ...@@ -81,8 +81,12 @@ Fields
.. attribute:: last_login .. attribute:: last_login
A datetime of the user's last login. Is set to the current date/time by A datetime of the user's last login.
default.
.. 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 .. attribute:: date_joined
......
...@@ -407,6 +407,26 @@ officially supports. ...@@ -407,6 +407,26 @@ officially supports.
This also includes dropping support for PostGIS 1.3 and 1.4 as these versions 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. 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 Miscellaneous
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment