from django.db import models from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ class ContentTypeManager(models.Manager): def get_for_model(self, model): """ Returns the ContentType object for the given model, creating the ContentType if necessary. """ opts = model._meta # The str() is needed around opts.verbose_name because it's a # django.utils.functional.__proxy__ object. ct, created = self.model._default_manager.get_or_create(app_label=opts.app_label, model=opts.object_name.lower(), defaults={'name': str(opts.verbose_name)}) return ct class ContentType(models.Model): name = models.CharField(maxlength=100) app_label = models.CharField(maxlength=100) model = models.CharField(_('python model class name'), maxlength=100) objects = ContentTypeManager() tag_enabled = models.BooleanField(default=False) tag_return_name = models.CharField(maxlength=100) tag_return_link = models.CharField(maxlength=100) class Meta: verbose_name = _('content type') verbose_name_plural = _('content types') db_table = 'django_content_type' ordering = ('name',) unique_together = (('app_label', 'model'),) def __str__(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) class Tag(models.Model): """A tag description""" name = models.CharField(maxlength=50) description = models.TextField(blank=True) icon = models.ImageField(upload_to="tags/",blank=True) owner = models.ForeignKey(User,blank=True) class Meta: ordering = ["name"] class Admin: pass def __str__(self): return self.name class TaggedItem(models.Model): """A tag on an item.""" tag = models.ForeignKey(Tag) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = models.GenericForeignKey() # TODO: Ordering: 21:55 < [530]> lucasvo: a custom manager using a sql query with a join and in_bulk # class Meta: # ordering = ["tag.name"] class Admin: pass def __str__(self): return self.tag.name # For testing purpose class Animal(models.Model): common_name = models.CharField(maxlength=150) latin_name = models.CharField(maxlength=150) tags = models.GenericRelation(TaggedItem) class Admin: pass def __str__(self): return self.common_name class Vegetable(models.Model): name = models.CharField(maxlength=150) is_yucky = models.BooleanField(default=True) tags = models.GenericRelation(TaggedItem) class Admin: pass def __str__(self): return self.name