如何在Django ORM中不转义字符?

huangapple go评论130阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年6月19日 17:57:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76505529.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定