Queryset:将字段与同一模型的另一个字段的子字符串进行比较

时间:2018-02-18 14:59:45

标签: python django django-models

我正在尝试检查Charfield(charfield_1)的前3个字符是否与同一模型的另一个Charfield(charfield_2)相似。

尝试:

User.objects.filter(charfield_2__startswith=Substr('charfield_1', 1, 3))

尝试使用F和Func但没有成功。 我一直在说:

django.db.utils.DataError: invalid input syntax for integer: "1%"
LINE 1: ...CE(REPLACE((SUBSTRING("model_name"."charfield_2", '1%', 3)),...

知道如何使这项工作?我想要一个使用ORM的解决方案来避免性能问题。

更新

在检查ORM生成的查询和错误消息后,当我使用startswith或包含查找表达式时,看起来第二个Substr参数被非整数替换。

ex:Substr(' charfield_1',1,3)由Substr替换(' charfield_1','%1%',3)

我使用的是版本2.0.2。

已开启并接受门票: https://code.djangoproject.com/ticket/29155

3 个答案:

答案 0 :(得分:3)

奇怪的错误,看起来像Django的错误?在家里,使用1.11,这有效:

User.objects.annotate(f1=Substr('charfield_1', 1, 3), f2=Substr('charfield_2', 1, 3)).filter(f1=F('f2'))

答案 1 :(得分:2)

您可以编写比较字段的User方法(或者如果您使用内置User类的函数)。

例如使用方法:

class User:
    def has_same_start(self):
       return self.charfield_1[0:3] == self.charfield_2[0:3]

然后为您的查询集:

all_users = User.objects.all()

# method1 - returns a list of User objects
my_selected_users = [user if user.has_same_start() for user in all_users]  

# method2 - returns a queryset
my_selected_users = User.objects.filter(pk__in=[user.pk if user.has_same_start() for user in all_users])

我不是说这是最好的解决方案。只是一个解决方案,但在性能方面可能还有更好的解决方案。但是,当我需要进行一些棘手的比较时,我更喜欢使用单独的方法,以便更容易进行单元测试。

答案 2 :(得分:0)

在检查ORM生成的查询和错误消息后,当我使用startswithcontains查找表达式时,看起来第二个Substr参数被非整数替换。

ex:Substr('charfield_1', 1, 3)Substr('charfield_1', '%1%', 3)

替换

我要报告django上的错误。 顺便说一下,我使用的是2.0.2版本。