Fixed #26977 -- Made abstract models raise TypeError when instantiating.

This commit is contained in:
Jacob Walls 2020-08-02 16:20:30 -04:00 committed by Mariusz Felisiak
parent 6c19230297
commit c7e7f176c1
4 changed files with 19 additions and 7 deletions

View File

@ -409,6 +409,8 @@ class Model(metaclass=ModelBase):
opts = self._meta
_setattr = setattr
_DEFERRED = DEFERRED
if opts.abstract:
raise TypeError('Abstract models cannot be instantiated.')
pre_init.send(sender=cls, args=args, kwargs=kwargs)

View File

@ -435,6 +435,8 @@ Miscellaneous
in the :class:`~django.apps.AppConfig` subclass if you need to prevent this
behavior. See :ref:`whats-new-3.2` for more details.
* Instantiating an abstract model now raises ``TypeError``.
.. _deprecated-features-3.2:
Features deprecated in 3.2

View File

@ -6,7 +6,7 @@ from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.hashers import get_hasher
from django.contrib.auth.models import (
AbstractUser, AnonymousUser, Group, Permission, User, UserManager,
AnonymousUser, Group, Permission, User, UserManager,
)
from django.contrib.contenttypes.models import ContentType
from django.core import mail
@ -215,8 +215,7 @@ class AbstractBaseUserTests(SimpleTestCase):
self.assertEqual(username, 'iamtheΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA
def test_default_email(self):
user = AbstractBaseUser()
self.assertEqual(user.get_email_field_name(), 'email')
self.assertEqual(AbstractBaseUser.get_email_field_name(), 'email')
def test_custom_email(self):
user = CustomEmailField()
@ -233,8 +232,8 @@ class AbstractUserTestCase(TestCase):
"connection": None,
"html_message": None,
}
abstract_user = AbstractUser(email='foo@bar.com')
abstract_user.email_user(
user = User(email='foo@bar.com')
user.email_user(
subject="Subject here",
message="This is a message",
from_email="from@domain.com",
@ -245,7 +244,7 @@ class AbstractUserTestCase(TestCase):
self.assertEqual(message.subject, "Subject here")
self.assertEqual(message.body, "This is a message")
self.assertEqual(message.from_email, "from@domain.com")
self.assertEqual(message.to, [abstract_user.email])
self.assertEqual(message.to, [user.email])
def test_last_login_default(self):
user1 = User.objects.create(username='user1')

View File

@ -279,10 +279,19 @@ class ParentListTests(SimpleTestCase):
class PropertyNamesTests(SimpleTestCase):
def test_person(self):
# Instance only descriptors don't appear in _property_names.
self.assertEqual(AbstractPerson().test_instance_only_descriptor, 1)
self.assertEqual(BasePerson().test_instance_only_descriptor, 1)
with self.assertRaisesMessage(AttributeError, 'Instance only'):
AbstractPerson.test_instance_only_descriptor
self.assertEqual(AbstractPerson._meta._property_names, frozenset(['pk', 'test_property']))
class ReturningFieldsTests(SimpleTestCase):
def test_pk(self):
self.assertEqual(Relation._meta.db_returning_fields, [Relation._meta.pk])
class AbstractModelTests(SimpleTestCase):
def test_abstract_model_not_instantiated(self):
msg = 'Abstract models cannot be instantiated.'
with self.assertRaisesMessage(TypeError, msg):
AbstractPerson()