Django 查询一个字段,获取匹配项列表;“之后”;基于其他字段的排序

Django 查询一个字段,获取匹配项列表;“之后”;基于其他字段的排序,django,Django,假设我有下表,用于从客户端获取增量更新列表。创建、修改或删除文章记录时,会在下表中添加一行 id | article_id | uuid ---|------------|------------------------------------- 1 | 56 | 78b69fa0-480b-11e1-b86c-0800200c9a66 2 | 23 | 87c4fe60-480b-11e1-b86c-0800200c9a66 3 | 78

假设我有下表,用于从客户端获取增量更新列表。创建、修改或删除文章记录时,会在下表中添加一行

id | article_id | uuid
---|------------|-------------------------------------
 1 |         56 | 78b69fa0-480b-11e1-b86c-0800200c9a66
 2 |         23 | 87c4fe60-480b-11e1-b86c-0800200c9a66
 3 |         78 | 903973f0-480b-11e1-b86c-0800200c9a66
 4 |         23 | bb3972d0-480b-11e1-b86c-0800200c9a66
 5 |         28 | f05fdd00-480b-11e1-b86c-0800200c9a66
客户端会记住上次同步时的uuid,并将其包含在下一个请求中。假设客户已经知道上述变更1和2;然后,他将uuid 87c4fe60-480b-11e1-b86c-0800200c9a66(id=2)包括在请求中。现在,我需要返回第3-5行。如果来自客户端的uuid不在表中,则应引发错误

简单的暴力方式是首先基于uuid进行搜索,然后使用找到的更改记录的id(在本例中为id=2)进行搜索,其中id>“found_id”(在本例中为id>2)


是否有一种更有效的查询方法,即以某种方式表示“在此uuid之后给我所有行,其中行按id升序排序”?

您可以让Django在一次db命中中完成此操作,尽管它仍然是一个查询+子查询,如下所示:

MyModel.objects.filter(id__gt=MyModel.objects.filter(
     uuid='whatever').values_list('id',))
您可以在where子句中使用Django的extra()方法和原始SQL。这将允许您在一个查询中选择所有文章。缺点是这是高度特定于数据库引擎的。假设您的模型是命名文章:

articles = Article.objects.extra(where=["id > (
    SELECT t2.id FROM "+Article._meta.db_table+" t2
    WHERE t2.uuid= '87c4fe60-480b-11e1-b86c-0800200c9a66'
    LIMIT 1)"]
).order_by('id').all())

是什么让你认为这种“简单的方式”效率低下?谢谢,我觉得子查询是必要的。不知道值列表,这使得解决方案优雅而简单。