summaryrefslogtreecommitdiffstats
path: root/webapp/django/contrib/contenttypes/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/django/contrib/contenttypes/models.py')
-rw-r--r--webapp/django/contrib/contenttypes/models.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/webapp/django/contrib/contenttypes/models.py b/webapp/django/contrib/contenttypes/models.py
new file mode 100644
index 0000000000..4df1edcc75
--- /dev/null
+++ b/webapp/django/contrib/contenttypes/models.py
@@ -0,0 +1,92 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import smart_unicode
+
+class ContentTypeManager(models.Manager):
+
+ # Cache to avoid re-looking up ContentType objects all over the place.
+ # This cache is shared by all the get_for_* methods.
+ _cache = {}
+
+ def get_for_model(self, model):
+ """
+ Returns the ContentType object for a given model, creating the
+ ContentType if necessary. Lookups are cached so that subsequent lookups
+ for the same model don't hit the database.
+ """
+ opts = model._meta
+ key = (opts.app_label, opts.object_name.lower())
+ try:
+ ct = self.__class__._cache[key]
+ except KeyError:
+ # Load or create the ContentType entry. The smart_unicode() is
+ # needed around opts.verbose_name_raw because name_raw might be a
+ # django.utils.functional.__proxy__ object.
+ ct, created = self.get_or_create(
+ app_label = opts.app_label,
+ model = opts.object_name.lower(),
+ defaults = {'name': smart_unicode(opts.verbose_name_raw)},
+ )
+ self._add_to_cache(ct)
+
+ return ct
+
+ def get_for_id(self, id):
+ """
+ Lookup a ContentType by ID. Uses the same shared cache as get_for_model
+ (though ContentTypes are obviously not created on-the-fly by get_by_id).
+ """
+ try:
+ ct = self.__class__._cache[id]
+ except KeyError:
+ # This could raise a DoesNotExist; that's correct behavior and will
+ # make sure that only correct ctypes get stored in the cache dict.
+ ct = self.get(pk=id)
+ self._add_to_cache(ct)
+ return ct
+
+ def clear_cache(self):
+ """
+ Clear out the content-type cache. This needs to happen during database
+ flushes to prevent caching of "stale" content type IDs (see
+ django.contrib.contenttypes.management.update_contenttypes for where
+ this gets called).
+ """
+ self.__class__._cache.clear()
+
+ def _add_to_cache(self, ct):
+ """Insert a ContentType into the cache."""
+ model = ct.model_class()
+ key = (model._meta.app_label, model._meta.object_name.lower())
+ self.__class__._cache[key] = ct
+ self.__class__._cache[ct.id] = ct
+
+class ContentType(models.Model):
+ name = models.CharField(max_length=100)
+ app_label = models.CharField(max_length=100)
+ model = models.CharField(_('python model class name'), max_length=100)
+ objects = ContentTypeManager()
+
+ class Meta:
+ verbose_name = _('content type')
+ verbose_name_plural = _('content types')
+ db_table = 'django_content_type'
+ ordering = ('name',)
+ unique_together = (('app_label', 'model'),)
+
+ def __unicode__(self):
+ return self.name
+
+ def model_class(self):
+ "Returns the Python model class for this type of content."
+ from django.db import models
+ return models.get_model(self.app_label, self.model)
+
+ def get_object_for_this_type(self, **kwargs):
+ """
+ Returns an object of this type for the keyword arguments given.
+ Basically, this is a proxy around this object_type's get_object() model
+ method. The ObjectNotExist exception, if thrown, will not be caught,
+ so code that calls this method should catch it.
+ """
+ return self.model_class()._default_manager.get(**kwargs)