Using a Custom Tag or Through Model¶
By default django-taggit
uses a “through model” with a
GenericForeignKey
on it, that has another ForeignKey
to an included
Tag
model. However, there are some cases where this isn’t desirable, for
example if you want the speed and referential guarantees of a real
ForeignKey
, if you have a model with a non-integer primary key, or if you
want to store additional data about a tag, such as whether it is official. In
these cases django-taggit
makes it easy to substitute your own through
model, or Tag
model.
Your intermediary model must be a subclass of
taggit.models.TaggedItemBase
with a foreign key to your content
model named content_object
. Pass this intermediary model as the
through
argument to TaggableManager
:
from django.db import models
from taggit.managers import TaggableManager
from taggit.models import TaggedItemBase
class TaggedFood(TaggedItemBase):
content_object = models.ForeignKey('Food')
class Food(models.Model):
# ... fields here
tags = TaggableManager(through=TaggedFood)
Once this is done, the API works the same as for GFK-tagged models.
To change the behavior in other ways there are a number of other classes you can subclass to obtain different behavior:
Class name | Behavior |
---|---|
TaggedItemBase |
Allows custom ForeignKeys to models. |
GenericTaggedItemBase |
Allows custom Tag models. |
ItemBase |
Allows custom Tag models and ForeignKeys to models. |
When providing a custom Tag
model it should be a ForeignKey
to your tag
model named "tag"
:
from django.db import models from django.utils.translation import ugettext_lazy as _ from taggit.managers import TaggableManager from taggit.models import TagBase, GenericTaggedItemBase class MyCustomTag(TagBase): # ... fields here class Meta: verbose_name = _("Tag") verbose_name_plural = _("Tags") # ... methods (if any) here class TaggedWhatever(GenericTaggedItemBase): # TaggedWhatever can also extend TaggedItemBase or a combination of # both TaggedItemBase and GenericTaggedItemBase. GenericTaggedItemBase # allows using the same tag for different kinds of objects, in this # example Food and Drink. # Here is where you provide your custom Tag class. tag = models.ForeignKey(MyCustomTag, related_name="%(app_label)s_%(class)s_items") class Food(models.Model): # ... fields here tags = TaggableManager(through=TaggedWhatever) class Drink(models.Model): # ... fields here tags = TaggableManager(through=TaggedWhatever)
-
class
TagBase
¶ -
slugify
(tag, i=None)¶ By default
taggit
usesdjango.template.defaultfilters.slugify()
to calculate a slug for a given tag. However, if you want to implement your own logic you can override this method, which receives thetag
(a string), andi
, which is eitherNone
or an integer, which signifies how many times the slug for this tag has been attempted to be calculated, it isNone
on the first time, and the counting begins at1
thereafter.
-