Getting next and previous objects in Django

大城市里の小女人 提交于 2019-12-18 02:03:30

问题


I'm trying to get the next and previous objects of a comic book issue. Simply changing the id number or filtering through date added is not going to work because I don't add the issues sequentially.

This is how my views are setup and it WORKS for prev_issue and does return the previous object, but it returns the last object for next_issue and I do not know why.

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]

回答1:


Add an order_by clause to ensure it orders by number.

next_issue = Issue.objects.filter(title=title, number__gt=issue.number).order_by('number').first()



回答2:


I know this is a bit late, but for anyone else, django does have a nicer way to do this, see https://docs.djangoproject.com/en/1.7/ref/models/instances/#django.db.models.Model.get_previous_by_FOO

So the answer here would be something something like

next_issue = Issue.get_next_by_number(issue, title=title)

Django managers to do that with a bit of meta class cleaverness.




回答3:


If it's required to find next and previous objects ordered by field values that can be equal and those fields are not of Date* type, the query gets slightly complex, because:

  • ordering on objects with same values limiting by [:1] will always produce same result for several objects;
  • object can itself be included in resulting set.

Here's are querysets that also take into account the primary keys to produce a correct result (assuming that number parameter from OP is not unique and omitting the title parameter as it's irrelevant for the example):

Previous:

prev_issue = (Issue.objects
    .filter(number__lte=issue.number, id__lt=instance.id)
    .exclude(id=issue.id)
    .order_by('-number', '-id')
    .first())

Next:

next_issue = (Issue.objects
    .filter(number__gte=issue.number, id__gt=instance.id)
    .exclude(id=issue.id)
    .order_by('number', 'id')
    .first())


来源:https://stackoverflow.com/questions/6021694/getting-next-and-previous-objects-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!