英文:
How to not escape a character in a Django ORM?
问题
我使用Django的ORM。
我不希望字符'%'被转义。
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)
我得到了'%harry\%magic\%school%'
:
select name, author, annotation from books
where name LIKE '%%' AND
author LIKE '%%' AND
annotation LIKE '%harry\%magic\%school%'
我想要得到'%harry%magic%school%'
:
select name, author, annotation from books
where name LIKE '%%' AND
author LIKE '%%' AND
annotation LIKE '%harry%magic%school%'
如何修复它?
英文:
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?
答案1
得分: 1
正如您可以在文档
中看到的,它会自动转义%
和_
,没有选项可以通过内置查找不进行转义。
因此,您可以使用.extra
来编写原始的SQL
,这在大多数情况下都不可取,即使对于最复杂的情况也是如此。或者,编写一个自定义查找:
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')
这将产生以下查询(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%
)
注意: 所有您的条件都针对name
字段,所以我假设这是错误的,并为每个变量更改了相应的字段匹配。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论