sql "LIKE" equivalent in django query

PythonSqlDjangoDjango ModelsDjango Queryset

Python Problem Overview


What is the equivalent of this SQL statement in django?

SELECT * FROM table_name WHERE string LIKE pattern;

How do I implement this in django? I tried

result = table.objects.filter( pattern in string )

But that did not work. How do i implement this?

Python Solutions


Solution 1 - Python

Use __contains or __icontains (case-insensitive):

result = table.objects.filter(string__contains='pattern')

The SQL equivalent is

SELECT ... WHERE string LIKE '%pattern%';

@Dmitri's answer below covers patterns like 'pattern%' or '%pattern'

Solution 2 - Python

contains and icontains mentioned by falsetru make queries like SELECT ... WHERE headline LIKE '%pattern%

Along with them, you might need these ones with similar behavior: startswith, istartswith, endswith, iendswith

making

SELECT ... WHERE headline LIKE 'pattern%

or

SELECT ... WHERE headline LIKE '%pattern

Solution 3 - Python

This can be done with Django's custom lookups. I have made the lookup into a Django-like-lookup application. After installing it the __like lookup with the % and _ wildcards will be enabled.

All the necessary code in the application is:

from django.db.models import Lookup
from django.db.models.fields import Field


@Field.register_lookup
class Like(Lookup):
    lookup_name = 'like'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return '%s LIKE %s' % (lhs, rhs), params

Solution 4 - Python

result = table.objects.filter(string__icontains='pattern')

Case insensitive search for string in a field.

Solution 5 - Python

In order to preserve the order of the words as in the sql LIKE '%pattern%' statement I use iregex, for example:

qs = table.objects.filter(string__iregex=pattern.replace(' ', '.*'))

string methods are immutable so your pattern variable will not change and with .* you'll be looking for 0 or more occurrences of any character but break lines.

By using the following to iterate over the pattern words:

qs = table.objects
for word in pattern.split(' '):
    qs = qs.filter(string__icontains=word)

the order of the words in your pattern will not be preserved, for some people that could work but in the case of trying to mimic the sql like statement I'll use the first option.

Solution 6 - Python

full example : lets say we have table called DjangTable with string field name file_name and we want to create Django filter equivalent to the query that match space in the string file_name in mysql:

SELECT * FROM DjangTable WHERE file_name LIKE '% %' 
class DjangTable(UTModel):


    ...
    file_name = models.CharField(max_length=255, null=False)
    ...

in Django using python it will be :

pattern = ' ' # same as mysql LIKE '% %'
DjangTable.objects.filter(file_name__contains=pattern)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAswin MurugeshView Question on Stackoverflow
Solution 1 - PythonfalsetruView Answer on Stackoverflow
Solution 2 - PythonDmitriy KuznetsovView Answer on Stackoverflow
Solution 3 - PythonPetr DlouhýView Answer on Stackoverflow
Solution 4 - PythonVenkat KotraView Answer on Stackoverflow
Solution 5 - PythonRoderich25View Answer on Stackoverflow
Solution 6 - PythonOmer AnisfeldView Answer on Stackoverflow