I added tags = TaggableManager(blank=True) to my models, but I want my tags to be case-insensitive.
I saw some snippets of work arounds for this and wanted to ask if there is an easy way to do it?
If I have to override some methods from the TaggableManager, please advise how can I do that?
Thanks in advance,
Arshavski Alexander.
I have used this snippet for a similar issue. A copy of the code (reprinted for posterity):
from django.db.models import Manager
from django.db.models.query import QuerySet
class CaseInsensitiveQuerySet(QuerySet):
def _filter_or_exclude(self, mapper, *args, **kwargs):
# 'name' is a field in your Model whose lookups you want case-insensitive by default
if 'name' in kwargs:
kwargs['name__iexact'] = kwargs['name']
del kwargs['name']
return super(CaseInsensitiveQuerySet, self)._filter_or_exclude(mapper, *args, **kwargs)
# custom manager that overrides the initial query set
class TagManager(Manager):
def get_query_set(self):
return CaseInsensitiveQuerySet(self.model)
# and the model itself
class Tag(models.Model):
name = models.CharField(maxlength=50, unique=True, db_index=True)
objects = TagManager()
def __str__(self):
return self.name
# now...
>>> tag = Tag(name='test')
>>> tag.save()
>>> Tag.objects.get(name='TEST')
<Tag: test>
Basically, you override the initial queryset so that all querysets take case insensitivity into account.
I am sure you have figured out solution by now :) Though I will put the answer as someone might hit this while searching -
Use https://github.com/shacker/django-taggit version of django-taggit.
It allows to configure TAGGIT_FORCE_LOWERCASE = True
It also allows you to filter stop words.
Recent versions of django-taggit support a TAGGIT_CASE_INSENSITIVE
setting, that should behave the way you're describing.