python - 如何仅使用 CASE 或 COALESCE 表达式来过滤 Django 查询集?

标签 python django postgresql

我将 Django 查询集基于一个功能正常的 postgres 查询,该查询具有以下 WHERE 条件:

... WHERE COALESCE("project_story"."owner_id" = [INSERT_USER_ID], "project_story"."published_date" IS NOT NULL)

英文:如果用户是故事的所有者,则包含该故事。如果用户不是所有者并且故事未发布,则将其排除。

理想情况下,Django ORM 应该允许类似以下内容:

    queryset = queryset.filter(
        Coalesce(
            Q(owner_id=user.id),
            Q(published_date__isnull=False)
        )
    )

但是在执行时,Django 抛出错误:

TypeError: 'Coalesce' object is not iterable

不幸的是,我需要在数据库级别进行条件过滤。

是否有允许使用合并表达式进行选择的符号或方法?

我不想使用 rawsql 或 queryset.extra。

最佳答案

这是我自己想出来的。由于尚未发布真正的答案,这是我的解决方案:

        return queryset.all().annotate(
            viewable=Case(
                When(owner_id=user.id, then=True),
                When(published_date__isnull=False, then=True),
                default=False,
                output_field=db.models.BooleanField()
            ),
        ).filter(
            viewable=True
        )

很难读,不是吗?生成的 SQL 也同样丑陋:

AND CASE WHEN ("project_story"."owner_id" = [INSERT USER ID]) THEN True WHEN ("project_story"."published_date" IS NOT NULL) THEN True ELSE False END = True) ORDER BY "project_story"."image_count" DESC

尽管使用 CASE 会得到与原始查询相同的结果,但我仍然希望代码更简洁。

在那之前,我会将我的问题标记为已回答。

关于python - 如何仅使用 CASE 或 COALESCE 表达式来过滤 Django 查询集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48270038/

相关文章:

python - 如何在 python 中以两位数 (00.00.00) 获取小时格式?

python - Django:您如何提供媒体/样式表并在模板中链接到它们

postgresql - 如何在 Kafka 中进行转换(PostgreSQL-> Red shift)

python - 产生扩展语法和发送方法

python - 从一个非常大的文件中选择一个随机行,从命令行

python - Django 模型表单对象的自动创建日期

django - 学习 Django 1.5 的最佳方式是什么?

java - 按列将数据插入 PostgreSQL 中的行

sql - 如何为 postgres 编写 DELETE CASCADE?

python - 从 python 项目生成可执行文件