Model Fields
Tagulous offers two new model field types:
tagulous.models.TagField - conventional tags using a
ManyToManyField
relationship.tagulous.models.SingleTagField - the same UI and functionality as a
TagField
but for a single tag, using aForeignKey
relationship.
These will automatically create the models for the tags themselves, or you can
provide a custom model to use instead with to
- see
Custom Tag Models for more details.
Tagulous lets you get and set string values using these fields, while still
leaving the underlying relationships available. For example, not only can
you assign a queryset or list of tag primary keys to a TagField
, but you
can also assign a list of tag names, or a tag string to parse.
Like a CharField
, changes made by assigning a value will not be committed
until the model is saved, although you can still make immediate changes by
calling the standard m2m methods add
, remove
and clear
.
If TAGULOUS_ENHANCE_MODELS
is True
(which it is by default -
see Settings), you can also use tag strings and lists of tag names in
get
and filter
, and model constructors and object.create()
- see
Tagged Models for more details.
Model Field Arguments
The SingleTagField
supports most standard ForeignKey
arguments, except
for to_field
and rel_class
.
The TagField
supports most normal ManyToManyField
arguments, except
for db_table
, through
and symmetrical
. Also note that blank
has
no effect at the database level, it is just used for form validation - as is
the case with a normal ManyToManyField
.
The related_name
will default to <field>_set
, as is normal for a
ForeignKey
or ManyToManyField
. If using the same tag table on multiple
fields, you will need to set this to something else to avoid clashes.
Auto-generating a tag model
If the to argument is not set, a tag model will be
auto-generated for you. It will be given a class name based on the names of
the tagged model and tag field; for example, the class name of the
auto-generated model for MyModel.tags
would be Tagulous_MyModel_tags
.
When auto-generating a model, any model option can be passed as a field argument - see the Automatic tag models example.
If you want to override the default base class, for convenience you can specify a custom base class for the auto tag model - see the to_base=MyTagModelBase argument for details.
Specifying a tag model
You can specify the tag model for the tag field to use with the to argument. You cannot specify any tag options.
to=MyTagModel
(or first unnamed argument)
Manually specify a tag model for this tag field. This can either be a
reference to the tag model class, or string reference to it in the format
app.model
.
This will normally be a custom tag model, which
must be a subclass of tagulous.models.TagModel
.
It can also be a reference to a tag model already auto-generated by another
tag field, eg to=MyOtherModel.tags.tag_model
, although you must be
confident that MyOtherModel
will always be defined first.
It can also be a string containing the name of the tag model, eg
to='MyTagModel'
. However, this is resolved using Django’s standard model
name resolution, so you have to reference auto-generated models by their class
name, not via the field - eg to='otherapp.Tagulous_MyOtherModel_tags'
.
If the tagged model for this field is also a custom tag model, you can
specify a recursive relationship as normal, using 'self'
.
If it is a custom tag model, it should have a TagMeta class. Fields which specify their tag model cannot provide new tag model options; they will take their options from the model - see Tag Options for more details.
This argument is optional; if omitted, a tag model will be auto-generated for you.
Default: Tagulous_<ModelName>_<FieldName>
(auto-generated)
to_base=MyTagModelBase
You can specify a base class to use for an auto-generated tag model, instead of
using TagModel
.
This can be useful on complex sites where multiple auto-generated tag models need to share common custom functionality - for example, tracking and filtering by user who creates the tags. This argument will allow you to define one base class and re-use it across your project with less boilerplate than defining many empty custom tag models.
Default: tagulous.models.TagModel
tagulous.models.SingleTagField
Unbound field
An unbound SingleTagField
(called on a model class, eg MyModel.tag
)
acts in the same way an unbound ForeignKey
field would, but also has:
tag_model
The related tag model
tag_options
A TagOptions class, containing the options from the tag model’s TagMeta or passed as arguments when initialising the field.
Bound to an instance
A bound SingleTagField
(called on an instance, eg instance.tags
) acts
in a similar way to a bound ForeignKey
, but with some differences:
- Assignment (setter)
A bound
SingleTagField
can be assigned a tag (an instance of the tag model) or a tag name.If it is passed
None
, a current tag will be cleared if it is set.The instance must be saved afterwards.
Example:
person.title = "Mr" person.save()
- Evaluation (getter)
The value of a bound
SingleTagField
will return an instance of the tag model. The tag may not exist in the database yet (itspk
may beNone
).Example:
tag = person.title report = "Tag %s used %d times " % (tag.name, tag.count)
The tag_model
and tag_options
attributes are not available on a bound
field. If you only have an instance of the tagged model, you can access them by
finding its class, eg type(person).title.tag_model
.
tagulous.models.TagField
Unbound field
An unbound TagField
(called on a model class, eg MyModel.tags
)
acts in the same way an unbound ManyToManyField
would, but also has:
tag_model
The related tag model
tag_options
A TagOptions class, containing the options from the tag model’s TagMeta or passed as arguments when initialising the field.
Bound to an instance
A bound TagField
(called on an instance, eg instance.tags
) acts
in a similar way to a bound ManyToManyField
, but with some differences:
- Assignment (setter)
A bound
TagField
can be assigned a tag string or an iterable of tags or tag names, eg a list of strings, or a queryset of instances of the tag model.If it is passed
None
, any current tags will be cleared.The instance must be saved afterwards.
Example:
person.skills = 'Judo, "Kung Fu"' person.save()
- Evaluation (getter)
A bound
TagField
will return a tagulous.models.TagRelatedManager object, which has functions to get and set tag values.