在Django过滤器中获取小写/无空格名称等于小写/无空格参数的对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Django过滤器中获取小写/无空格名称等于小写/无空格参数的对象相关的知识,希望对你有一定的参考价值。

我想得到所有products,其中name字段的无空格/小写版本等于Django中input_product_name参数的无空格/小写版本。我怎样才能做到这一点?

伪代码

def get_or_add_product(input_product_name):
    return Product.objects.filter(where no-space/lowercase version of name == input_product_name.strip().lower())
答案
## In-case spaces are to removed from beginning and end only
Product.objects.extra(
    where=["LOWER(TRIM(name)) = %s"],
    params=[input_product_name.strip().lower()]
)
## In-case spaces are to removed from everywhere in string
Product.objects.extra(
    where=["LOWER(REPLACE(name,' ','')) = %s"],
    params=[input_product_name.strip().lower()]
)

reference

另一答案

你可以使用Django的queryset annotateexpression及其Database Functions

例如,在您的情况下:

from django.db.models import Value
from django.db.models.functions import Lower, Replace


def get_product(input_product_name):
    input_product_name = input_product_name.lower().replace(' ', '')

    return Product.objects.annotate(
        lowered_nospace_name=Lower(Replace('name', Value(' '), Value('')))
    ).filter(
        lowered_name=input_product_name
    )

请注意,SQL的Trim()和Python的strip()只删除字符串开头和结尾的空格。例如,strip(' hello ') == 'hello'

安全说明

编写原始SQL可以帮助您,但是,如果您无法使用Django QuerySet方法表达您的查询,请仅将其用作最后的手段。 The Django team will deprecate未来的extra()功能,因为它可以打开SQL Injection攻击。

以上是关于在Django过滤器中获取小写/无空格名称等于小写/无空格参数的对象的主要内容,如果未能解决你的问题,请参考以下文章

@ 中的空格在链接中提及用户名和小写字母

如何检查 jinja2/django 模板中任何变量的大小写?

表单-过滤空格 小写变大写

Django模板中的Django不区分大小写字符串比较

django fields lookup methods(lookup类型)

如何使用 Django 模型进行不区分大小写的查询