Django queryset select where concat

Django queryset select where concat

我有一个这样的 sql 查询:

select *
from sys_user_promotion_record
where user_id=102 and concat(',' ,vendor_id, ',') like '%,1,%'

我怎样才能将该查询放入 Django 查询集中? 到目前为止,我设法制作了这个 Django 查询集:

SysUserPromotionRecord.objects.filter(user_id=102, vendor_id__contains=','+'1'+',')

如何将 concat(',' ,vendor_id, ',') 变成 Django 查询集? 我避免在我的代码中使用原始 sql 查询。谢谢。

这是 vendor_id 值示例:

执行sql时,会出现第1行和第2行。

您所做的应该有效,但我假设 vendor_id 是一个整数,因此没有任何逗号。如果这是真的,您的查询将始终 return 一个空查询集。

如果要查询vendor_id IN (vendor_id1, vendor_id12, ...)那么查询就是.filter(vendor_id__in=list_of_vendor_ids)

但是,如果您的供应商 ID 确实是一个字符串并且可以包含逗号,您的查询应该可以工作,但您也需要处理边缘情况,例如“...,11”、“11”和“11” ,...'。因此我建议这样

from django.db.models import Q
vendor_query = Q(vendor_id__iregex=r'^{0},|,{0},|,{0}$|^{0}$'.format(vendor_id))
SysUserPromotionRecord.objects.filter(vendor_query, user_id=102)

编辑:看到您的更改,答案的第一部分似乎可以忽略。

编辑:更新正则表达式,因为前一个 r',?{},?' 会 return 在搜索 1

时 returning 11 等情况的错误结果

在 mysql 中,like '%,1,%' 类型的查询是数据库杀手。

A B-tree index can be used for column comparisons in expressions that use the =, >, >=, <, <=, or BETWEEN operators. The index also can be used for LIKE comparisons if the argument to LIKE is a constant string that does not start with a wildcard character.

这里的根本问题是您没有规范化您的数据库。你不应该像这样存储你的数据的原因在这里有很好的解释:Is storing a delimited list in a database column really that bad? 您的首要任务是规范化数据库。

作为临时补丁查看 django Concat 函数。

http://dev.mysql.com/doc/refman/5.7/en/index-btree-hash.html