Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
102 lines (68 sloc) 3.687 kB
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"``:
.. code-block:: python
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
.. method:: slugify(tag, i=None)
By default ``taggit`` uses :func:`django.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 the ``tag``
(a string), and ``i``, which is either ``None`` or an integer, which
signifies how many times the slug for this tag has been attempted to be
calculated, it is ``None`` on the first time, and the counting begins
at ``1`` thereafter.
Jump to Line
Something went wrong with that request. Please try again.