如何将 Substr 与 F 表达式一起使用
How to use Substr with an F Expression
我正在尝试构建一个基于 fuzzystrmatch
postgres 扩展的 Func
类 的工具包。
例如,我有这个包装器,它接受一个表达式和一个搜索词以及 returns 编辑距离:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression,
search_term=search_term,
**extras
)
这样调用,使用 F Expression
:
Author.objects.annotate(lev_dist=Levenshtein(F('name'),'JRR Tolkien').filter(lev_dist__lte=2)
但是,如果此处的 'name'
字段大于 255,则会引发错误:
Both source and target can be any non-null string, with a maximum of 255 characters.
当我使用 Substr
注释时,我可以截断名称:
Author.objects.annotate(clipped_name=Substr(F('name'),1,250))
但我似乎无法弄清楚如何将该逻辑放入函数中,我将其放入 ExpressionWrapper
并根据 the docs 设置 output_field
:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression=ExpressionWrapper(Substr(expression, 1, 250), output_field=TextField()),
search_term=search_term,
**extras
)
虽然文档没有说得很清楚,只是通过实验发现答案是删除 expression
的额外定义并直接传入 ExpressionWrapper
作为第一个参数:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
ExpressionWrapper(Substr(expression, 1, 250), output_field=TextField()),
search_term=search_term,
**extras
)
我正在尝试构建一个基于 fuzzystrmatch
postgres 扩展的 Func
类 的工具包。
例如,我有这个包装器,它接受一个表达式和一个搜索词以及 returns 编辑距离:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression,
search_term=search_term,
**extras
)
这样调用,使用 F Expression
:
Author.objects.annotate(lev_dist=Levenshtein(F('name'),'JRR Tolkien').filter(lev_dist__lte=2)
但是,如果此处的 'name'
字段大于 255,则会引发错误:
Both source and target can be any non-null string, with a maximum of 255 characters.
当我使用 Substr
注释时,我可以截断名称:
Author.objects.annotate(clipped_name=Substr(F('name'),1,250))
但我似乎无法弄清楚如何将该逻辑放入函数中,我将其放入 ExpressionWrapper
并根据 the docs 设置 output_field
:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
expression=ExpressionWrapper(Substr(expression, 1, 250), output_field=TextField()),
search_term=search_term,
**extras
)
虽然文档没有说得很清楚,只是通过实验发现答案是删除 expression
的额外定义并直接传入 ExpressionWrapper
作为第一个参数:
class Levenshtein(Func):
"""This function calculates the Levenshtein distance between two strings:"""
template = "%(function)s(%(expressions)s, '%(search_term)s')"
function = "levenshtein"
def __init__(self, expression, search_term, **extras):
super(Levenshtein, self).__init__(
ExpressionWrapper(Substr(expression, 1, 250), output_field=TextField()),
search_term=search_term,
**extras
)