I use Django, ORM.
I don't want the character '%' to be escaped.
name=''
author=''
annotation = 'harry%magic%school'
criterion_name = Q(name__contains=cleaned_data['name'])
criterion_author = Q(author__contains=cleaned_data['author'])
criterion_annotation = Q(annotation__contains=cleaned_data['annotation'])
Book.objects.filter(criterion_name, criterion_author, criterion_annotation)
I get '%harry\%magic\%school%'
:
select name, author, annotation from books
where name LIKE '%%' AND
author LIKE '%%' AND
annotation LIKE '%harry\%magic\%school%'
I want to get '%harry%magic%school%'
:
select name, author, annotation from books
where name LIKE '%%' AND
author LIKE '%%' AND
annotation LIKE '%harry%magic%school%'
How to fix it?
As you can see in the docs
it will escape automatically both %
and _
, there is no option to not escape it by using built-in lookups.
So, you could use .extra
to write a raw SQL
which is undesirable in most cases, even for the most complex ones. Or, write a custom lookup:
lookups.py
class Like(models.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
models.CharField.register_lookup(Like)
views.py
from .lookups import Like
def some_view(request):
name = ''
author = ''
annotation = '%harry%magic%school%'
books = Book.objects.filter(
Q(name__contains=name),
Q(author__contains=author),
Q(annotation__like=annotation)
)
print(books.query)
return render(request, 'blank.html')
Which yields the following query (the output of print
):
SELECT "myapp_book"."id", "myapp_book"."name", "myapp_book"."author", "myapp_book"."annotation"
FROM "myapp_book"
WHERE (
"myapp_book"."name" LIKE %% ESCAPE '\'
AND "myapp_book"."author" LIKE %% ESCAPE '\'
AND "myapp_book"."annotation" LIKE %harry%magic%school%
)
Obs: All your criteria are against the name
field, so I just assumed it was wrong and changed it for each variable to match its respective field.