Fixed #5177 -- Changed content type creation to also remove the types for any orphaned entries (so it's now an "update" feature). Thanks, Rob Hudson.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6287 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-09-15 15:06:32 +00:00
parent 8e970f4835
commit 7c27f3e7ba
3 changed files with 23 additions and 13 deletions

View File

@ -149,6 +149,7 @@ answer newbie questions, and generally made Django that much better:
Sung-Jin Hong <serialx.net@gmail.com> Sung-Jin Hong <serialx.net@gmail.com>
Richard House <Richard.House@i-logue.com> Richard House <Richard.House@i-logue.com>
Robert Rock Howard <http://djangomojo.com/> Robert Rock Howard <http://djangomojo.com/>
Rob Hudson <http://rob.cogit8.org/>
Jason Huggins <http://www.jrandolph.com/blog/> Jason Huggins <http://www.jrandolph.com/blog/>
Hyun Mi Ae Hyun Mi Ae
Tom Insam Tom Insam

View File

@ -1,34 +1,43 @@
""" from django.contrib.contenttypes.models import ContentType
Creates content types for all installed models.
"""
from django.dispatch import dispatcher from django.dispatch import dispatcher
from django.db.models import get_apps, get_models, signals from django.db.models import get_apps, get_models, signals
from django.utils.encoding import smart_unicode from django.utils.encoding import smart_unicode
def create_contenttypes(app, created_models, verbosity=2): def update_contenttypes(app, created_models, verbosity=2):
from django.contrib.contenttypes.models import ContentType """
Creates content types for models in the given app, removing any model
entries that no longer have a matching model class.
"""
ContentType.objects.clear_cache() ContentType.objects.clear_cache()
content_types = list(ContentType.objects.filter(app_label=app.__name__.split('.')[-2]))
app_models = get_models(app) app_models = get_models(app)
if not app_models: if not app_models:
return return
for klass in app_models: for klass in app_models:
opts = klass._meta opts = klass._meta
try: try:
ContentType.objects.get(app_label=opts.app_label, ct = ContentType.objects.get(app_label=opts.app_label,
model=opts.object_name.lower()) model=opts.object_name.lower())
content_types.remove(ct)
except ContentType.DoesNotExist: except ContentType.DoesNotExist:
ct = ContentType(name=smart_unicode(opts.verbose_name_raw), ct = ContentType(name=smart_unicode(opts.verbose_name_raw),
app_label=opts.app_label, model=opts.object_name.lower()) app_label=opts.app_label, model=opts.object_name.lower())
ct.save() ct.save()
if verbosity >= 2: if verbosity >= 2:
print "Adding content type '%s | %s'" % (ct.app_label, ct.model) print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
# The presence of any remaining content types means the supplied app has an
# undefined model and can safely be removed, which cascades to also remove
# related permissions.
for ct in content_types:
if verbosity >= 2:
print "Deleting stale content type '%s | %s'" % (ct.app_label, ct.model)
ct.delete()
def create_all_contenttypes(verbosity=2): def update_all_contenttypes(verbosity=2):
for app in get_apps(): for app in get_apps():
create_contenttypes(app, None, verbosity) update_contenttypes(app, None, verbosity)
dispatcher.connect(create_contenttypes, signal=signals.post_syncdb) dispatcher.connect(update_contenttypes, signal=signals.post_syncdb)
if __name__ == "__main__": if __name__ == "__main__":
create_all_contenttypes() update_all_contenttypes()

View File

@ -25,7 +25,7 @@ class ContentTypeManager(models.Manager):
""" """
Clear out the content-type cache. This needs to happen during database Clear out the content-type cache. This needs to happen during database
flushes to prevent caching of "stale" content type IDs (see flushes to prevent caching of "stale" content type IDs (see
django.contrib.contenttypes.management.create_contenttypes for where django.contrib.contenttypes.management.update_contenttypes for where
this gets called). this gets called).
""" """
global CONTENT_TYPE_CACHE global CONTENT_TYPE_CACHE