Refs #18682 -- Edited explanation in stale content type deletion.
Follow up to 8db889eaf7
.
This commit is contained in:
parent
7399fee6c3
commit
e2dfa81ff7
|
@ -154,22 +154,20 @@ def update_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT
|
|||
for obj_type, objs in collector.data.items():
|
||||
if objs == {ct}:
|
||||
continue
|
||||
ct_info.append(' - %s object%s of type %s.%s:' % (
|
||||
ct_info.append(' - %s %s object(s)' % (
|
||||
len(objs),
|
||||
's' if len(objs) != 1 else '',
|
||||
obj_type._meta.app_label,
|
||||
obj_type._meta.model_name)
|
||||
)
|
||||
obj_type._meta.label,
|
||||
))
|
||||
|
||||
content_type_display = '\n'.join(ct_info)
|
||||
print("""Some content types in your database are stale and can be deleted.
|
||||
Any objects that depend on these content types will then also be deleted.
|
||||
The content types, and the dependent objects that would be deleted, are:
|
||||
Any objects that depend on these content types will also be deleted.
|
||||
The content types and dependent objects that would be deleted are:
|
||||
|
||||
%s
|
||||
|
||||
This list does not include data that might be in your database
|
||||
outside of Django's models.
|
||||
This list doesn't include any cascade deletions to data outside of Django's
|
||||
models (uncommon).
|
||||
|
||||
Are you sure you want to delete these content types?
|
||||
If you're unsure, answer 'no'.
|
||||
|
@ -191,7 +189,6 @@ If you're unsure, answer 'no'.
|
|||
class NoFastDeleteCollector(Collector):
|
||||
def can_fast_delete(self, *args, **kwargs):
|
||||
"""
|
||||
We always want to load the objects into memory so that we can display
|
||||
them to the user when asking confirmation.
|
||||
Always load related objects to display them when showing confirmation.
|
||||
"""
|
||||
return False
|
||||
|
|
|
@ -87,10 +87,9 @@ Minor features
|
|||
:mod:`django.contrib.contenttypes`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* When stale content types are detected during a management command, there is
|
||||
now an expansive list of objects that will be deleted. Previously, only
|
||||
the content type objects themselves were listed, even if there were objects
|
||||
with foreign keys towards the content types that would be deleted also.
|
||||
* When stale content types are detected after the ``migrate`` command, there's
|
||||
now a list of related objects such as ``auth.Permission``\s that will also be
|
||||
deleted. Previously, only the content types were listed.
|
||||
|
||||
:mod:`django.contrib.gis`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -131,6 +131,7 @@ class Post(models.Model):
|
|||
class ModelWithNullFKToSite(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
site = models.ForeignKey(Site, null=True, on_delete=models.CASCADE)
|
||||
post = models.ForeignKey(Post, null=True, on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
|
|
@ -389,21 +389,27 @@ class UpdateContentTypesTests(TestCase):
|
|||
def test_interactive_true_with_dependent_objects(self):
|
||||
"""
|
||||
interactive mode of update_contenttypes() (the default) should delete
|
||||
stale contenttypes and warn of dependent objects
|
||||
stale contenttypes and warn of dependent objects.
|
||||
"""
|
||||
Post.objects.create(title='post', content_type=self.content_type)
|
||||
post = Post.objects.create(title='post', content_type=self.content_type)
|
||||
# A related object is needed to show that a custom collector with
|
||||
# can_fast_delete=False is needed.
|
||||
ModelWithNullFKToSite.objects.create(post=post)
|
||||
contenttypes_management.input = lambda x: force_str("yes")
|
||||
with captured_stdout() as stdout:
|
||||
contenttypes_management.update_contenttypes(self.app_config)
|
||||
self.assertEqual(Post.objects.count(), 0)
|
||||
self.assertIn("1 object of type contenttypes_tests.post:", stdout.getvalue())
|
||||
self.assertIn("Deleting stale content type", stdout.getvalue())
|
||||
output = stdout.getvalue()
|
||||
self.assertIn('- Content type for contenttypes_tests.Fake', output)
|
||||
self.assertIn('- 1 contenttypes_tests.Post object(s)', output)
|
||||
self.assertIn('- 1 contenttypes_tests.ModelWithNullFKToSite', output)
|
||||
self.assertIn('Deleting stale content type', output)
|
||||
self.assertEqual(ContentType.objects.count(), self.before_count)
|
||||
|
||||
def test_interactive_true_without_dependent_objects(self):
|
||||
"""
|
||||
interactive mode of update_contenttypes() (the default) should delete
|
||||
stale contenttypes and inform there are no dependent objects
|
||||
stale contenttypes even if there aren't any dependent objects.
|
||||
"""
|
||||
contenttypes_management.input = lambda x: force_str("yes")
|
||||
with captured_stdout() as stdout:
|
||||
|
|
Loading…
Reference in New Issue