def add_tag(self, obj, tag_name):
     Associates the given object with a tag.
     tag_names = parse_tag_input(tag_name)
     if not len(tag_names):
         raise AttributeError(_('No tags were given: "%s".') % tag_name)
     if len(tag_names) > 1:
         raise AttributeError(_('Multiple tags were given: "%s".') % tag_name)
     tag_name = tag_names[0]
     if settings.FORCE_LOWERCASE_TAGS:
         tag_name = tag_name.lower()
     tag, created = self.get_or_create(slug=slugify(tag_name),
                                       defaults={'name': tag_name})
     if not created:
         # check if there is a preferred synonym for this tag
             related_tag = RelatedTag.objects.get(tag=tag, relation_type='=>')
         except RelatedTag.DoesNotExist:
             # there is a preferred synonym; use it instead of the original
             tag = related_tag.related_tag
     ctype = ContentType.objects.get_for_model(obj)
         tag=tag, content_type=ctype,
 def _save(self, **kwargs):  # signal, sender, instance):
     Save tags back to the database
     tags = self._get_instance_tag_cache(kwargs["instance"])
     Tag.objects.update_tags(kwargs["instance"], tags)
     if self.relate:
         if self.category:
             cat_tag, c = Tag.objects.get_or_create(slug=slugify(self.category), defaults={"name": self.category})
             RelatedTag.objects.relate(cat_tag, ">", tags)
 def save(self, *args, **kwargs):
     self.slug = slugify(
     super(Tag, self).save(*args, **kwargs)