============
Introduction
============

Features
========

* Easy to install - simple requirements, simple syntax, lots of options
* Based on ForeignKey and ManyToManyField, so it's easy to query
* Autocomplete support built in, if you want it
* Supports multiple independent tag fields on a single model
* Can be used as a CharField with dynamic choices
* Supports trees of nested tags, for detailed categorisation
* Admin support for managing tags and tagged models


.. _quickstart:

Quickstart
==========

Install ``django-tagulous``, add ``tagulous`` to ``INSTALLED_APPS``, then start
adding tag fields to your model::

    from django.db import models
    from tagulous.models import SingleTagField, TagField

    class Person(models.Model):
        name = models.CharField(max_length=255)
        title = SingleTagField(initial="Mr, Mrs, Miss, Ms")
        skills = TagField()

A ``SingleTagField`` is based on a ``ForeignKey``, and a ``TagField`` is based
on a ``ManyToManyField``, which both have relationships to a ``TagModel`` -
which is automatically created for you if you don't specify one. The main
difference is that you can create new tags by setting their values using
strings - and in the case of a ``TagField``, lists or querysets::

    myperson = Person.objects.create(name='Bob', title='Mr', skills='run, hop')
    # myperson.skills == 'run, hop'
    myperson.skills = ['jump', 'kung fu']
    myperson.save()
    # myperson.skills == 'jump, "kung fu"'
    runners = Person.objects.filter(skills='run')

Because these fields are still based on ``ForeignKey`` and ``ManyToManyField``,
you can use normal Django queries::

    qs = MyRelatedModel.objects.filter(
        person__skills__name__in=['run', 'jump'],
    )

As well as this you also get:

* unicode support and automatic :ref:`slug generation <model_slug>`
* tag field support in public :doc:`forms <forms>` and the :doc:`admin <admin>`
  site, including autocompletion
* easy to build :ref:`tag clouds <tag_clouds>`
* ability to nest tags in :doc:`trees <models/tag_trees>` for more complex
  categorisation

Take a look at the :doc:`usage` to see what else you can do, or read on through
the :doc:`documentation <index>` to see exactly how everything works.


Glossary
========

This documentation uses a few terms to explain the ways tags are stored and
set:

Tagged model
    A model which has been tagged using :doc:`models/fields`.

Tag model
    A model where the tag definition is stored. It must be a subclass of
    :ref:`tagmodel`, but will be auto-generated by a tag field if it is not
    explicitly set.

Tag
    An instance of a tag model

Tag name
    The unique name of a tag, eg ``"run"``. This is the value stored on the
    ``name`` attribute of a tag model.

Tag string
    A tag string is a list of tag names stored in a single string, in tag
    format, eg ``"run, jump, hop"``. The format of this string is defined
    by the :doc:`parser`.


Comparison with other tagging libraries
=======================================

Popular tagging libraries for Django include:
* `django-taggit <https://github.com/alex/django-taggit>`_
* `django-tagging <https://github.com/Fantomas42/django-tagging>`_
* `django-tagging-ng <https://github.com/svetlyak40wt/django-tagging-ng>`_

If you are already using one of these, read
:ref:`converting_to_tagulous` to see what is involved in switching to Tagulous.

Tagulous is easier to use and has more features:

Simpler syntax
--------------
Tagulous provides a ``TagField`` model field which is based on a
``ManyToManyField``. It lets you set and query tag objects like a normal
M2M field, but also lets you use tag strings and lists of tag names.
It operates like any native field - see the
:doc:`models/fields` documentation and
:ref:`this example <example_auto_tagmodel>` for more details.

By comparison, django-tagging uses a registration function to add a
pseudo-field to the model, and uses generic relations behind the
scenes. Generic relations tend to be second-class citizens in Django - they
are often slower and lack functionality compared to native FK and M2M
fields; for example, aggregation is
`currently impossible <https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#generic-relations-and-aggregation>`_.
This means django-tagging has a more convoluted syntax and queries are more
complex and limited - see
`their docs <http://django-tagging.readthedocs.org/en/develop/#id4>`_
for details.

django-taggit uses a manager which is similar to django-tagging's pseudo-field
and provides a better interface than django-tagging, but still uses generic
relations by default. Again, the syntax to set and query tags isn't as simple
as Tagulous - see
`their docs <https://django-taggit.readthedocs.org/en/latest/api.html>`_
for details.

Separate tag models
-------------------
By default tagulous automatically creates a new tag model for each field.
This means you can have multiple tag fields on a single model, each with
their own sets of tags. However, because it uses normal FK/M2M
relationships behind the scenes, you can also link tag fields together to
share tags between them - see the :doc:`models/tag_models` documentation
for more details.

You can also easily define custom tag models in Tagulous - see the
:ref:`custom_tag_models` documentation and
:ref:`this example <example_custom_tag_model>` for more details.

django-taggit can be configured to use custom models so it can have
separate sets of tags, but requires a bit more work - see
`their docs <https://django-taggit.readthedocs.org/en/latest/custom_tagging.html>`_
for details. django-tagging does not support separate sets of tags or
custom models.

More customisable
-----------------
Tagulous is designed to be configurable. For example, it lets you protect
tags from being removed when they're no longer in use, they can be case
sensitive, forced to lowercase, you can specify a maximum number of tags
for a field, and whether or not space should be used as a delimiter.
See the :doc:`tag_options` documentation for more details.

django-tagging only lets you force tags to lowercase, and django-taggit
only lets you toggle case sensitivity.

Built-in autocomplete
---------------------
Tagulous has built-in support for autocomplete; tags can either be embedded
into the page, or queried using the ajax views provided. It uses Select2,
but it has been designed to be easy to switch that out for something else
using :ref:`autocomplete adaptors <autocomplete_adaptors>`.

The JavaScript and Python code is closely integrated - the tag parser has
been implemented in both to ensure tag strings are treated consistently.

Take a look at
`the front-end demo <http://radiac.net/projects/django-tagulous/demo/>`_
to see how autocomplete works in practice.

Neither django-tagging and django-taggit support autocomplete out of the
box, although both have third-party apps which can add that functionality.

Better admin support
--------------------
Tagulous tag fields are first-class citizens in Django's admin site. You
can show them in ``list_display``, use them to filter your model, and can
register tag models to rename and merge tags. Tag fields and autocomplete
work throughout admin forms and inlines. See the
:doc:`admin` documentation for more details.

django-tagging and django-taggit tags cannot be shown in ``list_display``,
and there are no special admin tools.

Single tag mode
---------------
The standard ``TagField`` is based on a ``ManyToManyField`` for
conventional tagging, but Tagulous also provides a ``SingleTagField``,
which is based on ``ForeignKey``. This acts more like a ``CharField`` with
``choices`` which can be added to by the user at runtime. See the
:doc:`models/fields` documentation for more details.

django-tagging and django-taggit don't have an equivalent feature.

Hierarchical tag trees
----------------------
Tagulous has a tree mode, which lets you create sub-tags using the ``/``
character in a tag name. You can query and navigate a tag tree as you would
expect (querying for parents, siblings, children, descendants etc), as well
as rename and merge subtrees from your code or the Django admin. See the
:doc:`models/tag_trees` documentation for more details.

django-tagging and django-taggit don't have an equivalent feature.

And there's more
----------------
Tagulous is packed with small features which make it easy to work with,
such as:
* a more robust :doc:`tag string parser <parser>` with better support for
  quoted tags.
* automatic :ref:`slug <model_slug>` generation, and :ref:`path <model_path>`
  generation for tree tags.
* tag model managers and querysets have a :ref:`weight <queryset_weight>`
  method to make it easy to build custom tag clouds.
