sql - django get_next_by_FOO() 查询是如何工作的?
问题描述
我想知道 get_next_by_FOO()/get_previous_by_FOO() 如何从数据库中获取数据。有人知道那个的SQL代码吗?谁能告诉我它是如何在幕后工作的?
解决方案
方法在django/db/models/base.py
【GitHub】文件中实现:
def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): if not self.pk: raise ValueError("get_next/get_previous cannot be used on unsaved objects.") op = 'gt' if is_next else 'lt' order = '' if is_next else '-' param = getattr(self, field.attname) q = Q(**{'%s__%s' % (field.name, op): param}) q = q | Q(**{field.name: param, 'pk__%s' % op: self.pk}) qs = self.__class__._default_manager.using(self._state.db).filter(**kwargs).filter(q).order_by( '%s%s' % (order, field.name), '%spk' % order ) try: return qs[0] except IndexError: raise self.DoesNotExist("%s matching query does not exist." % self.__class__._meta.object_name)
如果is_next
您True
查询get_next_by_FOO
,并且False
如果您查询get_previous_by_FOO
.
因此,get_next_by_FOO
这将创建一个如下所示的查询:
Model.objects.filter(
Q(FOO__gt=current_foo)
Q(FOO=current_foo, pk__gt=current_pk)
).order_by('FOO', 'pk')[0]
因此,它将搜索字段相同但主键更大或字段(严格)更大的第一个Model
对象。FOO
FOO
因此,这将导致查询如下所示:
SELECT *
FROM model
WHERE FOO > current_FOO
OR (FOO = current_FOO AND id > current_pk)
ORDER BY FOO ASC, id ASC
LIMIT 1
因此,它将旨在通过对记录进行排序并获取第一个记录来找到该元素。
对于get_previous_by_FOO
,查询是类似的,只是>
被替换为<
并且我们以相反的方式排序:
SELECT *
FROM model
WHERE FOO < current_FOO
OR (FOO = current_FOO AND id < current_pk)
ORDER BY FOO DESC, id DESC
LIMIT 1
推荐阅读
- angular - 如何在 Angular Web 应用程序中收听来自 Chrome 扩展程序的 background.js 的消息?
- python - 如何在这个 json 文件中获取“属性”的键并在 DataFrame 中设置它们的列名?
- php - Wordpress 网站昨晚宕机了
- amazon-web-services - CDN vs S3在同一个区域,那么CDN有什么用
- liferay - 如何自定义 Liferay Form 发送的电子邮件
- tensorflow - 为什么我不能将 GPU 与 tensorflow 一起使用?
- docusignapi - DocuSign - 在没有 API 身份验证的情况下将信封发送到电子邮件
- load-testing - 在加特林有条件地保存响应
- javascript - “无法对未安装的组件执行 React 状态更新。” 仅当功能组件是 Child 时
- java - ConsumerRecords 在 Kafka、Java 中始终为空,但 Future
isDone 方法结果为真