sql «LIKE» équivalent dans la requête django


108

Quel est l'équivalent de cette instruction SQL dans django?

SELECT * FROM table_name WHERE string LIKE pattern;

Comment implémenter cela dans django? j'ai essayé

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

Mais ça n'a pas marché. Comment mettre en œuvre cela?

Réponses:


200

Utilisez __containsou __icontains(insensible à la casse):

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

L'équivalent SQL est

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

22
Et pour la recherche insensible à la casse, utilisez __icontains ->result = table.objects.filter(string__icontains='pattern')
Hitesh Garg

13
Cette réponse ne couvre qu'un sous-ensemble des modèles possibles. Il ne gérerait pas un modèle comme %a%b%.
kasperd

@kasperd, essayez:result = table.objects.filter(string__contains='a').filter(string__contains='b')
LS

1
@LS Cela correspondrait à bace LIKE %a%b%qui ne le serait pas.
kasperd

2
Cette réponse est incomplète pour les raisons exposées ci-dessus. Il devrait également inclure les informations contenues dans la réponse de @ Dmitry.
medley56

34

contient et icontains mentionnés par falsetru font des requêtes comme SELECT ... WHERE headline LIKE '%pattern%

Avec eux, vous pourriez avoir besoin de ceux-ci avec un comportement similaire: commence par , istarts avec , se termine par , iends avec

fabrication

SELECT ... WHERE headline LIKE 'pattern%

ou

SELECT ... WHERE headline LIKE '%pattern


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

Recherche insensible à la casse pour une chaîne dans un champ.


2
Bien, mais la même réponse avait déjà été donnée près de trois ans plus tôt.
LS

3

Afin de conserver l'ordre des mots comme dans l'instruction sql LIKE '% pattern%', j'utilise iregex, par exemple:

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

Les méthodes de chaîne sont immuables, donc votre variable de motif ne changera pas et avec. * vous rechercherez 0 ou plusieurs occurrences de n'importe quel caractère sauf les lignes de rupture.

En utilisant ce qui suit pour parcourir les mots de modèle:

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

l'ordre des mots dans votre modèle ne sera pas préservé, pour certaines personnes qui pourraient fonctionner mais dans le cas où j'essaierai d'imiter l'instruction sql like, j'utiliserai la première option.


2

Cela peut être fait avec les recherches personnalisées de Django . J'ai fait la recherche dans une application de recherche de type Django . Après l'avoir installé, la __likerecherche avec les caractères génériques %et _sera activée.

Tout le code nécessaire dans l'application est:

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.