我想知道get_next_by_FOO()/ get_previous_by_FOO()如何从数据库中获取数据。有谁知道SQL代码吗?谁能告诉我它在后台如何工作?
该方法在django/db/models/base.py
[GitHub]文件中实现:
django/db/models/base.py
如果查询 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
被>
替换并且我们以相反的方式进行排序:
<