首页 > 解决方案 > 如何使用自定义函数注释 Django QuerySet?

问题描述

agr_suitable_code我需要在模型字段上使用自定义函数注释查询集。

看起来像这样

def strip_accents(s):
    return ''.join(c for c in unicodedata.normalize('NFD', s)
                   if unicodedata.category(c) != 'Mn')


def agr_suitable_code(on_distro_code):
    upper_str = on_distro_code.upper()
    return strip_accents(upper_str)

这里没什么特别的,该函数接受一个字符串并返回它并进行一些更改。agr_like_code然后我尝试用它进行注释,因为没有这个带注释的字段就无法实现以下查询。

        related_params[distro.id] = table.objects.filter(
            ProductId__in=[map["ProductId"] for map in related_maps_by_distro.values("ProductId")]
        ).annotate(
            agr_like_code=Func(F("DistributionParameterId__Code"), function=agr_suitable_code),
         prod_to_param_exists=
            Exists(AgrDistributionProductParameter.objects.filter(ProductId=context['product'],
                                                                  DistributionParameterId__Code=OuterRef(
                                                                      "agr_like_code")).values('id')),
            has_agr_param=Case(
                When(Q(agr_like_code__in=agr_parameter_codes)
                     & Q(DistributionParameterId__Code__in=agr_param_map_codes_distro)
                     , then=2),
                When(Q(agr_like_code__in=agr_parameter_codes), then=1),
                default=0,
                output_field=models.IntegerField(),
etc ..

我试图以agr_like_code=Func(F("DistributionParameterId__Code"), function=agr_suitable_code) 多种方式制定这条线,但没有成功。

我收到的当前错误是

django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '<'. (102) (SQLExecDirectW); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '<'. (102); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '<'. (102); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '<'. (102); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Statement(s) could not be prepared. (8180)")

我知道 Django 文档建议编写自定义 SQL 查询,例如

class ConcatPair(Func):
    ...
    function = 'CONCAT'
    ...

    def as_mysql(self, compiler, connection, **extra_context):
        return super().as_sql(
            compiler, connection,
            function='CONCAT_WS',
            template="%(function)s('', %(expressions)s)",
            **extra_context
        )

但我不能用这个agr_suitable_code功能真正做到这一点。

有没有办法用这个自定义的简单函数注释查询集?任何提示将不胜感激。先感谢您。

标签: djangodjango-modelsdjango-querysetdjango-annotate

解决方案


推荐阅读