Fixed #28313 -- Added model name max length check of 100 characters in contrib.contentttypes.

This commit is contained in:
michaldabski 2017-06-15 21:44:20 +01:00 committed by Tim Graham
parent 44a7b98abb
commit d381914aef
4 changed files with 44 additions and 1 deletions

View File

@ -1,5 +1,7 @@
from django.apps import AppConfig from django.apps import AppConfig
from django.contrib.contenttypes.checks import check_generic_foreign_keys from django.contrib.contenttypes.checks import (
check_generic_foreign_keys, check_model_name_lengths,
)
from django.core import checks from django.core import checks
from django.db.models.signals import post_migrate, pre_migrate from django.db.models.signals import post_migrate, pre_migrate
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -17,3 +19,4 @@ class ContentTypesConfig(AppConfig):
pre_migrate.connect(inject_rename_contenttypes_operations, sender=self) pre_migrate.connect(inject_rename_contenttypes_operations, sender=self)
post_migrate.connect(create_contenttypes) post_migrate.connect(create_contenttypes)
checks.register(check_generic_foreign_keys, checks.Tags.models) checks.register(check_generic_foreign_keys, checks.Tags.models)
checks.register(check_model_name_lengths, checks.Tags.models)

View File

@ -1,6 +1,7 @@
from itertools import chain from itertools import chain
from django.apps import apps from django.apps import apps
from django.core.checks import Error
def check_generic_foreign_keys(app_configs=None, **kwargs): def check_generic_foreign_keys(app_configs=None, **kwargs):
@ -18,3 +19,23 @@ def check_generic_foreign_keys(app_configs=None, **kwargs):
for field in fields: for field in fields:
errors.extend(field.check()) errors.extend(field.check())
return errors return errors
def check_model_name_lengths(app_configs=None, **kwargs):
if app_configs is None:
models = apps.get_models()
else:
models = chain.from_iterable(app_config.get_models() for app_config in app_configs)
errors = []
for model in models:
if len(model._meta.model_name) > 100:
errors.append(
Error(
'Model names must be at most 100 characters (got %d).' % (
len(model._meta.model_name),
),
obj=model,
id='contenttypes.E005',
)
)
return errors

View File

@ -668,6 +668,7 @@ The following checks are performed when a model contains a
* **contenttypes.E003**: ``<field>`` is not a ``ForeignKey``. * **contenttypes.E003**: ``<field>`` is not a ``ForeignKey``.
* **contenttypes.E004**: ``<field>`` is not a ``ForeignKey`` to * **contenttypes.E004**: ``<field>`` is not a ``ForeignKey`` to
``contenttypes.ContentType``. ``contenttypes.ContentType``.
* **contenttypes.E005**: Model names must be at most 100 characters.
``sites`` ``sites``
--------- ---------

View File

@ -1,5 +1,6 @@
from unittest import mock from unittest import mock
from django.contrib.contenttypes.checks import check_model_name_lengths
from django.contrib.contenttypes.fields import ( from django.contrib.contenttypes.fields import (
GenericForeignKey, GenericRelation, GenericForeignKey, GenericRelation,
) )
@ -216,3 +217,20 @@ class GenericRelationTests(SimpleTestCase):
id='fields.E001', id='fields.E001',
) )
]) ])
@isolate_apps('contenttypes_tests', attr_name='apps')
class ModelCheckTests(SimpleTestCase):
def test_model_name_too_long(self):
model = type('A' * 101, (models.Model,), {'__module__': self.__module__})
self.assertEqual(check_model_name_lengths(self.apps.get_app_configs()), [
checks.Error(
'Model names must be at most 100 characters (got 101).',
obj=model,
id='contenttypes.E005',
)
])
def test_model_name_max_length(self):
type('A' * 100, (models.Model,), {'__module__': self.__module__})
self.assertEqual(check_model_name_lengths(self.apps.get_app_configs()), [])