【问题标题】:Filtering order in djangodjango中的过滤顺序
【发布时间】:2017-10-29 08:43:36
【问题描述】:

我有兴趣按特定顺序按 django orm 过滤表。基本上,这是通过两个字段进行的简单搜索 - 名称和描述。我想首先按“名称”字段并发对结果进行排序,然后按“描述”字段并发排序。以下是原始 sql 的示例:

WITH checkpoints AS (SELECT * FROM checkpoints_view WHERE ...) SELECT * FROM checkpoints WHERE name ILIKE '%KEYWORD%' UNION ALL SELECT * FROM checkpoints WHERE description ILIKE '%KEYWORD%' AND name NOT ILIKE '%KEYWORD%';

如何在 django orm 中生成这样的 sql?

谢谢大家

P.S.:对不起,如果我的英语不正确,我来自非英语国家

class Checkpoint(models.Model, ReadOnlyModel):
    id = models.IntegerField(primary_key=True) 
    name = models.CharField(max_length=255, verbose_name='Наименование')
    code_number = models.CharField(max_length=255, verbose_name="Код остановки")
    description = models.CharField(max_length=255, verbose_name="Описание")
    coordinate = models.PointField(verbose_name="Координата")
    routes = ArrayField(models.IntegerField())
    dates = ArrayField(models.DateField()) 

    class Meta: 
        db_table = 'checkpoints_view' 
        managed = False

几乎所有人都对,但我希望结果是按行开始排序的,它通过了名称字段的过滤器,然后,在这一切之后 - 行,它通过了描述字段的过滤器

【问题讨论】:

  • 请分享您的模型

标签: django django-rest-framework django-orm


【解决方案1】:

我认为您的代码可以在没有 CTE 的情况下编写:

Checkpoint.objects.filter(
    Q(name__icontains='keyword') |
    (~Q(name__icontains='keyword') & Q(description__icontains='keyword')))

【讨论】:

  • 你有什么问题??你为什么只对我的回答投反对票??我对你做了什么 ??其他人给出了相同的答案,但您特别反对我的答案?
  • @Exprator 你来这里是为了获得轻松的 SO 声誉。您提到的另一个解决方案将返回正确的结果,尽管它不是最佳解决方案。您的解决方案不能解决问题 - 如果您思考或尝试,您会发现它会给出与问题中发布的查询不同的结果。没有什么私人的,我看到一个不正确的答案并投了反对票。
  • 说“不是最佳解决方案”让我觉得因为我总是使用我的解决方案(我认为它更具可读性,但不知道它可能效率较低)所以尝试了两种解决方案(我的和你的)在一个简单的 django 模型上,使用非常简单的查询 (pk>10) or (pk < 10 and pk !=3) 并使用 print(q.query) 检查 django sql 查询,它们都生成了相同的 sql 查询。
  • 我不确定复杂查询,可能复杂查询不同
  • @aliva 最好安装django-extensions 包并使用./manage.py debugsqlshell,它更方便并且会将所有查询打印到控制台。当我说您的解决方案不是最佳时,我错了 - 我检查了一下,似乎 Django 在您的情况下也生成了最佳 SQL 查询。
【解决方案2】:

AFAIK,Django ORM 在它生成的查询中不使用 CTE。那是因为它们在不同的 RDBMS 中具有不同的行为,并且在 mysql 和 sqlite 中根本不支持。

因此,如果您想在查询中使用 CTE,您唯一的选择是 raw query。类似的东西

queryset = MyModel.objects.raw('WITH checkpoints AS (SEL ....')

【讨论】:

  • 这是问题所在,它现在已经在原始 sql 上工作,但我想用 django orm 方式实现这个谢谢你的回答
  • 顺便说一句,我并不是说严格使用“WITH”关键字,它可以是两个选择并联合。
  • 你问了一个问题,我们回答了。您的想法我们无法回答。
【解决方案3】:
results = Checkpoint.objects.filter(
    name__icontains='str_1',
) | Checkpoint.objects.filter(
    description__icontains='str_2',
).exclude(
    name__icontains='str_3',
)

【讨论】:

    猜你喜欢
    • 2013-11-27
    • 2020-07-10
    • 2014-11-15
    • 2021-07-08
    • 2012-06-10
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    相关资源
    最近更新 更多