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

xzlaal3s  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(108)

我使用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%'

如何修复它?

mm5n2pyu

mm5n2pyu1#

正如你在docs中看到的,它会自动转义%_,没有选项可以通过使用内置查找来不转义它。
因此,您可以使用.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%
)

**Obs:**您的所有条件都是针对name字段的,所以我只是假设它是错误的,并为每个变量更改它以匹配其各自的字段。

相关问题