============
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
==========

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

    from django.db import models
    import tagulous
    
    class Person(models.Model):
        name = models.CharField(max_length=255)
        title = tagulous.models.SingleTagField(initial="Mr, Mrs, Miss, Ms")
        skills = tagulous.models.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
=======================================

Tagulous takes a different approach to other tagging libraries for Django by
directly extending ``ForeignKey`` and ``ManyToManyField``, with the option to
automatically create separate tag models without using generic relations. This
means it has a simpler syntax, and has more flexibility and reliability when
managing and querying tags.

It also aims to be a self-contained package by including all commonly-required
tagging functionality, such as autocomplete and admin extensions.

If you are already using another tagging library, see
:ref:`converting_to_tagulous` for what is involved in switching to Tagulous.


Separate tag models, no generic relations
-----------------------------------------

The first popular tagging library for Django was the now-defunct
`django-tagging <https://github.com/brosner/django-tagging>`_, which has been
replaced by the fork
`django-tagging-ng <https://github.com/svetlyak40wt/django-tagging-ng>`_.
These use a registration approach to add a pseudo-field to the model
(as ``tags`` by default), which provides a simple interface for setting and
getting tags. It also adds a manager (default name ``tagged``) for retrieving
models based on tags. The popular
`django-taggit <https://github.com/alex/django-taggit>`_ is added to models
using a manager, which is essentially django-tagging's ``tags`` pseudo-field
and ``tagged`` manager in one.

Both libraries store tags in a single tag model, which means there can only be
one set of tags for the site - different models cannot use different sets of
tags, and a model can only ever have one tag field. In contrast, Tagulous
assumes the tags for each field should be kept separate, and lets you
explicitly state which fields should share tags.

They also store the relationship between tags and tagged items using a
``GenericForeignKey``, but generic relations tend to be second-class citizens
in Django - often slower, lacking functionality and having more bugs compare
to standard ``ForeignKey`` and ``ManyToManyField`` relationships. Tagulous only
uses these standard relationships, so all database queries and aggregations
will function exactly as expected.

While django-taggit can be configured to operate in a similar way to Tagulous
with separate tag models, and ``through`` models so that standard relational
field queries can be used, it uses a more verbose syntax to do so, and the
custom models have to be explicitly created.


Tagulous does more
------------------

Traditional tagging is based on a many-to-many relationship (where an object
can have many tags), but Tagulous also supports one-to-many ``ForeignKey``
relationships with its ``SingleTagField`` - where an object can only have one
tag, but that tag can be managed using a similar API and form widget to a
regular ``TagField``. This can be used to effectively create a ``CharField``
with ``choices`` that can be extended by users.

Tagulous also has optional support for :doc:`tag trees <models/tag_trees>` -
hierarchical nested tags for more detailed categorisation.

Unlike django-tagging-ng and django-taggit, Tagulous also has built-in support
for autocomplete in public and admin sites, using Select2 (and this can be
customised using :ref:`autocomplete adaptors <autocomplete_adaptors>`).

Tagulous also has a more robust :doc:`tag string parser <parser>` with better
support for quoted tags, which is also implemented in JavaScript for full 
compatibility with client-side autocompletion.
