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

Refs #18682 -- Edited explanation in stale content type deletion.

Follow up to 8db889ea.
üst 7399fee6
......@@ -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:
......
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