Estoy tratando de construir un conjunto de herramientas de clases Func basadas en la extensión fuzzystrmatch postgres.
Por ejemplo, tengo este contenedor que toma una Expresión y un término de búsqueda y devuelve la distancia levenshtein:
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 ) Llamado así, usando una F Expression :
Author.objects.annotate(lev_dist=Levenshtein(F('name'),'JRR Tolkien').filter(lev_dist__lte=2) Sin embargo, si el campo 'name' aquí es mayor que 255, arroja un error:
Tanto el origen como el destino pueden ser cualquier cadena no nula, con un máximo de 255 caracteres.
Puedo truncar el nombre cuando anoto usando Substr :
Author.objects.annotate(clipped_name=Substr(F('name'),1,250)) Pero parece que no puedo descifrar cómo colocar esa lógica dentro de la función, que estoy colocando dentro de un ExpressionWrapper y configurando el output_field según los documentos :
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 )Aunque los documentos no dejan esto muy claro, solo experimentando resulta que la respuesta fue eliminar la definición adicional de expression y pasar ExpressionWrapper directamente como el primer argumento:
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 )