app/django/contrib/contenttypes/models.py
changeset 54 03e267d67478
equal deleted inserted replaced
53:57b4279d8c4e 54:03e267d67478
       
     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     # Cache to avoid re-looking up ContentType objects all over the place.
       
     8     # This cache is shared by all the get_for_* methods.
       
     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             # 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)},
       
    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             # This could raise a DoesNotExist; that's correct behavior and will
       
    43             # make sure that only correct ctypes get stored in the cache dict.
       
    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     
       
    70     class Meta:
       
    71         verbose_name = _('content type')
       
    72         verbose_name_plural = _('content types')
       
    73         db_table = 'django_content_type'
       
    74         ordering = ('name',)
       
    75         unique_together = (('app_label', 'model'),)
       
    76 
       
    77     def __unicode__(self):
       
    78         return self.name
       
    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)