首页 > 解决方案 > 如何编写在其内部连接中使用复杂“on”子句的 Django 查询?

问题描述

我正在使用 Django、Python 3.7 和 PostgreSQL 9.5。我有这些模型:

class Article(models.Model):
    ...
    label = models.TextField(default='', null=True)


class Label(models.Model):
    name = models.CharField(max_length=200)

我想编写一个 Django 查询,从 Labels 表中检索其标签包含名称的所有文章。在 PostGres 中,我可以像这样构造我的查询:

select a.* from myapp_article a join myapp_label l on a.label ilike '%' || l.name || '%';

但由于“on”子句和“ilike”,我不知道如何在 Django 中实现这一点。我该如何解决这个问题?

标签: pythondjangopython-3.xpostgresqlinner-join

解决方案


如果您必须对文章的标签进行不区分大小写的搜索以匹配名称,那么您可以使用正则表达式并将所有标签名称的平面列表传递给它,如下所示:

Article.objects.filter(label__iregex=r'(' + '|'.join(Label.objects.all().values_list('name', flat=True)) + ')')

上面的查询所做的是,它制作了一个扁平的标签列表:

['label1' , 'label2', 'label3']

然后字符串像这样连接:

'(label1|label2|label3)'

并使用了类似的 SQL 查询:

SELECT * from FROM "app_article" WHERE "app_article"."label" ~* (label1|label2|label3)

否则,对于区分大小写的方法,您可以使用以下方法:

names_list = Label.objects.all().values_list('name', flat=True)
Article.objects.filter(label__in=names_list)

推荐阅读