Forms
Normally tag fields will be used in a ModelForm; they will automatically
use the correct form field and widget to render tag fields with your
selected autocomplete adaptor.
To save tag fields, just call the form.save() method as you would normally.
However, because django_tagulous.models.TagField is based on a ManyToManyField, if
you call form.save(commit=False) you will need to call form.save_m2m()
after to save the tags.
See the ModelForms example for how this works in practice.
Form field classes
You can also use Tagulous form fields outside model forms by using the django_tagulous.forms.SingleTagField and django_tagulous.forms.TagField form fields - see the Forms without models example for how this works in practice.
Tag forms fields take standard Django core field arguments
such as label and required.
django_tagulous.forms.SingleTagField
This field accepts three new arguments:
tag_optionsA TagOptions instance, containing form options (model options will be ignored).
autocomplete_tagsAn iterable of tags to be embedded for autocomplete. This can either be a queryset of tag objects, or a list of tag objects or strings.
can_create_errorCustom error message to use when can_create on
tag_optionsblocks a new tag being submitted. Defaults to “You cannot create new tags.”
The clean method returns a single tag name string, or None if the
value is empty.
django_tagulous.forms.TagField
This field accepts the same three new arguments as a SingleTagField:
tag_optionsA TagOptions instance, containing form options (model options will be ignored).
autocomplete_tagsAn iterable of tags to be embedded for autocomplete. This can either be a queryset of tag objects, or a list of tag objects or strings.
can_create_errorCustom error message to use when can_create on
tag_optionsblocks a new tag being submitted. Defaults to “You cannot create new tags.”
The clean method returns a sorted list of unique tag names (a list of
strings) - or an empty list if there are no tags.
django_tagulous.forms.TaggedInlineFormSet
In most cases Tagulous works with Django’s default inline model formsets, and you don’t need to do anything special.
However, there is a specific case where it doesn’t: when you create an inline
formset for tagged models, with a tag as their parent model - eg when you edit
a tag and its corresponding instances of the tagged model. That is when you
must use the TaggedInlineFormSet class. For example:
from django_tagulous.models import SingleTagField
from django_tagulous.forms import TaggedInlineFormSet
class Person(models.Model):
name = models.CharField(max_length=255)
title = SingleTagField(initial='Mr, Mrs')
PersonInline = forms.models.inlineformset_factory(
Person.title.tag_model,
Person,
formset=TaggedInlineFormSet,
)
This would allow you to generate a formset for all Person objects which
use a specific title tag.
Tagulous will automatically apply this fix in the admin site when the tag model admin is registered using the standard Django admin API.
Without the TaggedInlineFormSet class in this situation, the tag count will
be incorrect when adding tagged model instances, and editing will fail because
the default formset will try to use the tag name as a primary key.
The TaggedInlineFormSet class will only perform actions under this specific
relationship, so is safe to use in other situations.
Autocomplete Adaptors
Tagulous uses a javascript file it calls an adaptor to apply your chosen
autocomplete library to the Tagulous form field.
Tagulous supports Select2 and Dropulous out of
the box; if you want to use a different library, you will need to add it
to your project’s static files, and add the relative path under STATIC_URL to the
appropriate TAGULOUS_ settings.
Tagulous includes the following adaptors:
Dropulous
An adaptor for Dropulous, a modern minimal dependency-free JavaScript library.
This will be the default adaptor from version 3.0.0. See Upgrading from 2.1.0 for how to switch to it early.
- Path:
tagulous/adaptor/dropulous.js
Select2 (version 4)
The default adaptor, for Select2.
- Path:
tagulous/adaptor/select2-4.js
Autocomplete settings should be a dict:
deferIf
True, the tag field will not be initialised automatically; you will need to callTagulous.select2(el)on it from your own javascript. This is useful for fields which are used as templates to dynamically generate more.For example, to use this adaptor with a django-dynamic-formset which uses a
formTemplate, set{'defer': True}, then configure the formset with:added: function ($row) { Tagulous.select2($row.find('input[data-tagulous]')); }
Note that when used with inline formsets which raise the
formset:addedevent (like in the Django admin site), Tagulous will automatically try to register tag fields in new formsets ifdefer=False.widthThis is the same as in Select2’s documentation, but the Tagulous default is
resolveinstead ofoff, for the best chance of working without complication.
All other settings will be passed to the Select2 constructor.
Select 2 (version 3)
The legacy adaptor for Select2 version 3.
- Path:
tagulous/adaptor/select2-3.js
Listening for changes
Both dropulous and select2 keep the original field’s value in sync, and fire a
change event whenever a tag is added or removed. This means external code can listen
on the field itself, the same as any other form field:
document.querySelector('[name=skills]').addEventListener('change', () => {
// ...
});
or for jQuery:
$(document).on('change', '[name=skills]', () => {
// ...
});
Writing a custom autocomplete adaptor
Writing a custom adaptor should be fairly self-explanatory - take a look at the included adaptors to see how they work. It’s mostly just a case of pulling data out of the HTML field, and fiddling with it a bit to pass it into the library’s constructor.
Tagulous puts certain settings on the HTML field’s data- attribute:
data-tagulousAlways
true- used to identify a tagulous class to JavaScriptdata-tag-typeSet to
singlewhen aSingleTagField, otherwise not present.data-tag-listJSON-encoded list of tags.
data-tag-urlURL to request tags
data-tag-optionsJSON-encoded dict of tag options
In addition to the dict from
TagOptionscontaining the field’s Form Options, there will also be:requiredA boolean indicating whether the form field is required or not
These settings can be used to initialise your autocomplete library of choice.
You should initialise it using data-tag-options’s autocomplete_settings
for default values.
For consistency with Tagulous’s python parser, try to replace your autocomplete library’s parser with Tagulous’s javascript parser.
If you write an adaptor which you think would make a good addition to this project, please do send it in or make a pull request on github - see Contributing for more information.