1
from django.db import models
2
from django.utils.translation import ugettext_lazy as _
3
from django.utils.encoding import smart_unicode
5
class ContentTypeManager(models.Manager):
7
# Cache to avoid re-looking up ContentType objects all over the place.
8
# This cache is shared by all the get_for_* methods.
11
def get_for_model(self, model):
13
Returns the ContentType object for a given model, creating the
14
ContentType if necessary. Lookups are cached so that subsequent lookups
15
for the same model don't hit the database.
18
key = (opts.app_label, opts.object_name.lower())
20
ct = self.__class__._cache[key]
22
# Load or create the ContentType entry. The smart_unicode() is
23
# needed around opts.verbose_name_raw because name_raw might be a
24
# django.utils.functional.__proxy__ object.
25
ct, created = self.get_or_create(
26
app_label = opts.app_label,
27
model = opts.object_name.lower(),
28
defaults = {'name': smart_unicode(opts.verbose_name_raw)},
30
self._add_to_cache(ct)
34
def get_for_id(self, id):
36
Lookup a ContentType by ID. Uses the same shared cache as get_for_model
37
(though ContentTypes are obviously not created on-the-fly by get_by_id).
40
ct = self.__class__._cache[id]
42
# This could raise a DoesNotExist; that's correct behavior and will
43
# make sure that only correct ctypes get stored in the cache dict.
45
self._add_to_cache(ct)
48
def clear_cache(self):
50
Clear out the content-type cache. This needs to happen during database
51
flushes to prevent caching of "stale" content type IDs (see
52
django.contrib.contenttypes.management.update_contenttypes for where
55
self.__class__._cache.clear()
57
def _add_to_cache(self, ct):
58
"""Insert a ContentType into the cache."""
59
model = ct.model_class()
60
key = (model._meta.app_label, model._meta.object_name.lower())
61
self.__class__._cache[key] = ct
62
self.__class__._cache[ct.id] = ct
64
class ContentType(models.Model):
65
name = models.CharField(max_length=100)
66
app_label = models.CharField(max_length=100)
67
model = models.CharField(_('python model class name'), max_length=100)
68
objects = ContentTypeManager()
71
verbose_name = _('content type')
72
verbose_name_plural = _('content types')
73
db_table = 'django_content_type'
75
unique_together = (('app_label', 'model'),)
77
def __unicode__(self):
80
def model_class(self):
81
"Returns the Python model class for this type of content."
82
from django.db import models
83
return models.get_model(self.app_label, self.model)
85
def get_object_for_this_type(self, **kwargs):
87
Returns an object of this type for the keyword arguments given.
88
Basically, this is a proxy around this object_type's get_object() model
89
method. The ObjectNotExist exception, if thrown, will not be caught,
90
so code that calls this method should catch it.
92
return self.model_class()._default_manager.get(**kwargs)