1 from django.db import models
2 from django.utils.translation import ugettext_lazy as _
3 from django.utils.encoding import smart_unicode
4
5 -class ContentTypeManager(models.Manager):
6
7
8
9 _cache = {}
10
11 - def get_for_model(self, model):
12 """
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.
16 """
17 opts = model._meta
18 key = (opts.app_label, opts.object_name.lower())
19 try:
20 ct = self.__class__._cache[key]
21 except KeyError:
22
23
24
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)},
29 )
30 self._add_to_cache(ct)
31
32 return ct
33
34 - def get_for_id(self, id):
35 """
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).
38 """
39 try:
40 ct = self.__class__._cache[id]
41 except KeyError:
42
43
44 ct = self.get(pk=id)
45 self._add_to_cache(ct)
46 return ct
47
48 - def clear_cache(self):
49 """
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
53 this gets called).
54 """
55 self.__class__._cache.clear()
56
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
63
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()
69
76
77 - def __unicode__(self):
79
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)
84
85 - def get_object_for_this_type(self, **kwargs):
86 """
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.
91 """
92 return self.model_class()._default_manager.get(**kwargs)
93