我正在尝试获取漫画书问题的下一个和前一个对象。简单地更改ID号或过滤添加日期是行不通的,因为我没有按顺序添加问题。
这是我的视图设置方式,它适用于prev_issue
并且确实返回上一个对象,但它返回next_issue
的最后一个对象,我不知道为什么。
def issue(request, issue_id):
issue = get_object_or_404(Issue, pk=issue_id)
title = Title.objects.filter(issue=issue)
prev_issue = Issue.objects.filter(title=title).filter(number__lt=issue.number)[0:1]
next_issue = Issue.objects.filter(title=title).filter(number__gt=issue.number)[0:1]
答案 0 :(得分:38)
添加order_by
子句以确保按number
订购。
next_issue = Issue.objects.filter(title=title, number__gt=issue.number).order_by('number').first()
答案 1 :(得分:25)
我知道这有点晚了,但对于其他任何人来说,django确实有更好的方法来做到这一点,请参阅https://docs.djangoproject.com/en/1.7/ref/models/instances/#django.db.models.Model.get_previous_by_FOO
所以这里的答案就像是
next_issue = Issue.get_next_by_number(issue, title=title)
Django经理用一点元类切割器来做到这一点。
答案 2 :(得分:5)
如果需要找到下一个和以前的对象,按字段值排序可以相等且这些字段不是在Date*
类型中,查询稍微复杂,因为:
[:1]
将始终为多个对象生成相同的结果; 这里的查询集还考虑了产生正确结果的主键(假设来自OP的number
参数不是唯一的,并省略了title
参数,因为它&#39 ;与例子无关):
<强>上:强>
prev_issue = (Issue.objects
.filter(number__lte=issue.number, id__lt=instance.id)
.exclude(id=issue.id)
.order_by('-number', '-id')
.first())
下一步:强>
next_issue = (Issue.objects
.filter(number__gte=issue.number, id__gt=instance.id)
.exclude(id=issue.id)
.order_by('number', 'id')
.first())
答案 3 :(得分:0)
from functools import partial, reduce
from django.db import models
def next_or_prev_instance(instance, qs=None, prev=False, loop=False):
if not qs:
qs = instance.__class__.objects.all()
if prev:
qs = qs.reverse()
lookup = 'lt'
else:
lookup = 'gt'
q_list = []
prev_fields = []
if qs.query.extra_order_by:
ordering = qs.query.extra_order_by
elif qs.query.order_by:
ordering = qs.query.order_by
elif qs.query.get_meta().ordering:
ordering = qs.query.get_meta().ordering
else:
ordering = []
ordering = list(ordering)
if 'pk' not in ordering and '-pk' not in ordering:
ordering.append('pk')
qs = qs.order_by(*ordering)
for field in ordering:
if field[0] == '-':
this_lookup = (lookup == 'gt' and 'lt' or 'gt')
field = field[1:]
else:
this_lookup = lookup
q_kwargs = dict([(f, get_model_attr(instance, f))
for f in prev_fields])
key = "%s__%s" % (field, this_lookup)
q_kwargs[key] = get_model_attr(instance, field)
q_list.append(models.Q(**q_kwargs))
prev_fields.append(field)
try:
return qs.filter(reduce(models.Q.__or__, q_list))[0]
except IndexError:
length = qs.count()
if loop and length > 1:
return qs[0]
return None
next_instance = partial(next_or_prev_instance, prev=False)
prev_instance = partial(next_or_prev_instance, prev=True)
答案 4 :(得分:-1)
next_obj_id = int(current_obj_id) + 1 next_obj = Model.objects.filter(id=next_obj_id).first()
prev_obj_id= int(current_obj_id) - 1 prev_obj = Model.objects.filter(id=prev_obj_id).first()
#你没有什么可失去的...这对我有用