pythondjangodjango-modelsdjango-rest-frameworkdjango-taggit

Lowercase Field values django models queryset


I have a Model of an object and few tags are assigned to the object of this model. Tags may be uppercased, lowercased or mix of both cases. I want to write a queryset which will return those object which has same tags which I provided. Note: I am using django-taggit module.
Views.py

def home(request):
    book = Book.objects.filter(tags__name__in= map(lambda s:s.lower(), ['harry-potter', 'Champak', 'Physics']))
    print(book)
    return HttpResponse("Books Retrieved")

Models.py

from django.db import models
from django.utils.translation import ugettext_lazy as _

from taggit.managers import TaggableManager
from taggit.models import GenericUUIDTaggedItemBase, TaggedItemBase

class UUIDTaggedItem(GenericUUIDTaggedItemBase, TaggedItemBase):
    class Meta:
        verbose_name = _("Tag")
        verbose_name_plural = _("Tags")

class Book(models.Model):
    name = models.CharField(max_length=100)
    details = models.TextField(blank=True)
    tags = TaggableManager(through=UUIDTaggedItem, blank = True)

Now I want to return all the books which have tags mentioned as 'HArry-Potter', 'HARRY-POTTER', or any other word.

PS: If anyhow we can lower the 'tags__name__in' List, our work will be done.


Solution

  • You can make a Q object where you filter case insensitive with:

    from django.db.models import Q
    
    data = ['harry-potter', 'Champak', 'Physics']
    
    qfilter = Q(
        *[Q(tags__name__iexact=item) for item in data],
        _connector=Q.OR
    )
    
    Book.objects.filter(
        qfilter
    )

    The __iexact [Django-doc] will match case insensitively with each item in data.