Queryset in django without case-sensitive

3

I have a question about Querysets in Django.

I need to do a search on a field that is a Charfield, but the search I'm doing appears to be case sensitive. And I wanted that when looking for 'Stack' the search would return 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)

The variable that contains the value to be searched is a keyword.

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

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

Node.objects.filter(nome__contains = 'internet')
    
asked by anonymous 29.05.2015 / 03:17

1 answer

1

Several Django filters have a case-sensitive variant and another variant that does not. In the case of contains is icontains :

Node.objects.filter(nome__icontains = keyword)

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

As for your other question, you can call filter with no parameters (or maybe all , I'm not sure) and then call additional methods on QuerySet . Each method call further restricts what the query does (SQL will only actually execute when you try to read the result of QuerySet , until 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 OU instead of AND only) 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)
    
29.05.2015 / 09:14