Queryset on Django without case-sensitive

Asked

Viewed 616 times

3

I have a question about Querysets in Django.

I need to search a field that’s a Charfield, only the research I’m doing appears to be case sensitive. And I wanted that when searching for 'Stack' the search returns a field that is 'stack overflow'. Here is the model of the class whose search will be performed.

class Node(models.Model):

objects = GChartsManager()

idnode = models.IntegerField(db_column='idSITE', primary_key=True, editable=False)  # Field name made lowercase.
nome = models.CharField(db_column='NAME', max_length=45)  # Field name made lowercase.
informacoes = models.CharField(db_column='INFORMATION', max_length=45, blank=True)  # Field name made lowercase.

class Meta:
    managed = False
    db_table = 'site'

And the code I use to perform the search

Node.objects.filter(nome__contains = keyword)

Keyword being the variable containing the value to be searched.

And I would also like to know how to create an empty queryset and "add items" to it. For example I want to make a queryset with these 2 results, I want both to be in the same query set.

Node.objects.filter(nome__contains = 'Stack')

Node.objects.filter(nome__contains = 'internet')

1 answer

2

Several Django filters have a variant that takes uppercase/lowercase and another variant that does not. In the case of contains is the icontains:

Node.objects.filter(nome__icontains = keyword)

There is also the exact and iexact, startswith and istartswith, etc..

As for your other question, you can call filter without any parameter (or maybe all, I’m not sure) and then call additional methods in QuerySet. Each method call further restricts what the query makes (SQL will only be executed in fact when you try to read the result of QuerySet, until then you can modify it at will). An example would be:

qs = Node.objects.filter()                   # select * from app_node;

qs = qs.filter(nome__contains = 'Stack')     # select * from app_node
                                             # where nome like 'Stack';

qs = qs.filter(nome__contains = 'internet')  # select * from app_node
                                             # where nome like 'Stack'
                                             # and nome like 'internet';

qs = qs[10:30] # select * from app_node
               # where nome like 'Stack' and nome like 'internet'
               # limit 20 offset 10;

x = qs[0] # Aqui o SQL será executado, e você não pode mais mexer na QuerySet

A more flexible option (which even allows you to combine conditions with OR instead of just AND) is using Q():

from django.db.models import Q

tem_stack = Q(nome__contains = 'Stack')
tem_internet = Q(nome__contains = 'internet')

e = Node.objects.filter(tem_stack & tem_internet)
ou = Node.objects.filter(tem_stack | tem_internet)
  • Very well detailed, I use another framework, but I will take a look at this now due to this part of Models +1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.