1
from django.contrib.contenttypes.models import ContentType
1
from django.apps import apps
2
2
from django.db import DEFAULT_DB_ALIAS, router
3
from django.db.models import get_apps, get_model, get_models, signals, UnavailableApp
3
from django.db.models import signals
4
4
from django.utils.encoding import smart_text
5
5
from django.utils import six
6
6
from django.utils.six.moves import input
9
def update_contenttypes(app, created_models, verbosity=2, db=DEFAULT_DB_ALIAS, **kwargs):
9
def update_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs):
11
11
Creates content types for models in the given app, removing any model
12
12
entries that no longer have a matching model class.
14
if not app_config.models_module:
15
get_model('contenttypes', 'ContentType')
16
except UnavailableApp:
18
ContentType = apps.get_model('contenttypes', 'ContentType')
19
if not router.allow_syncdb(db, ContentType):
22
if not router.allow_migrate(using, ContentType):
22
25
ContentType.objects.clear_cache()
23
app_models = get_models(app)
26
# They all have the same app_label, get the first one.
27
app_label = app_models[0]._meta.app_label
27
app_label = app_config.label
29
30
(model._meta.model_name, model)
30
for model in app_models
31
for model in app_config.get_models())
33
36
# Get all the content types
34
37
content_types = dict(
36
for ct in ContentType.objects.using(db).filter(app_label=app_label)
39
for ct in ContentType.objects.using(using).filter(app_label=app_label)
50
53
for (model_name, model) in six.iteritems(app_models)
51
54
if model_name not in content_types
53
ContentType.objects.using(db).bulk_create(cts)
56
ContentType.objects.using(using).bulk_create(cts)
56
59
print("Adding content type '%s | %s'" % (ct.app_label, ct.model))
58
61
# Confirm that the content type is stale before deletion.
60
if kwargs.get('interactive', False):
61
content_type_display = '\n'.join([
64
content_type_display = '\n'.join(
62
65
' %s | %s' % (ct.app_label, ct.model)
63
66
for ct in to_remove
65
68
ok_to_delete = input("""The following content types are stale and need to be deleted:
84
87
print("Stale content types remain.")
87
def update_all_contenttypes(verbosity=2, **kwargs):
88
for app in get_apps():
89
update_contenttypes(app, None, verbosity, **kwargs)
91
signals.post_syncdb.connect(update_contenttypes)
90
def update_all_contenttypes(**kwargs):
91
for app_config in apps.get_app_configs():
92
update_contenttypes(app_config, **kwargs)
95
signals.post_migrate.connect(update_contenttypes)
93
98
if __name__ == "__main__":
94
99
update_all_contenttypes()