|
1 from django.contrib.contenttypes.models import ContentType |
|
2 from django.dispatch import dispatcher |
|
3 from django.db.models import get_apps, get_models, signals |
|
4 from django.utils.encoding import smart_unicode |
|
5 |
|
6 def update_contenttypes(app, created_models, verbosity=2): |
|
7 """ |
|
8 Creates content types for models in the given app, removing any model |
|
9 entries that no longer have a matching model class. |
|
10 """ |
|
11 ContentType.objects.clear_cache() |
|
12 content_types = list(ContentType.objects.filter(app_label=app.__name__.split('.')[-2])) |
|
13 app_models = get_models(app) |
|
14 if not app_models: |
|
15 return |
|
16 for klass in app_models: |
|
17 opts = klass._meta |
|
18 try: |
|
19 ct = ContentType.objects.get(app_label=opts.app_label, |
|
20 model=opts.object_name.lower()) |
|
21 content_types.remove(ct) |
|
22 except ContentType.DoesNotExist: |
|
23 ct = ContentType(name=smart_unicode(opts.verbose_name_raw), |
|
24 app_label=opts.app_label, model=opts.object_name.lower()) |
|
25 ct.save() |
|
26 if verbosity >= 2: |
|
27 print "Adding content type '%s | %s'" % (ct.app_label, ct.model) |
|
28 # The presence of any remaining content types means the supplied app has an |
|
29 # undefined model and can safely be removed, which cascades to also remove |
|
30 # related permissions. |
|
31 for ct in content_types: |
|
32 if verbosity >= 2: |
|
33 print "Deleting stale content type '%s | %s'" % (ct.app_label, ct.model) |
|
34 ct.delete() |
|
35 |
|
36 def update_all_contenttypes(verbosity=2): |
|
37 for app in get_apps(): |
|
38 update_contenttypes(app, None, verbosity) |
|
39 |
|
40 dispatcher.connect(update_contenttypes, signal=signals.post_syncdb) |
|
41 |
|
42 if __name__ == "__main__": |
|
43 update_all_contenttypes() |