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

问题描述 投票:0回答:2

我想得到所有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())
python regex django filter
2个回答
2
投票
## 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


4
投票

你可以使用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攻击。

© www.soinside.com 2019 - 2024. All rights reserved.