Skip to content

Instantly share code, notes, and snippets.

@olivx
Last active October 10, 2018 13:27
Show Gist options
  • Save olivx/d18c3d8093782328ef29474981ec281d to your computer and use it in GitHub Desktop.
Save olivx/d18c3d8093782328ef29474981ec281d to your computer and use it in GitHub Desktop.
my_applicants = Model.object.all()
context['next'] = next_in_order(obj, qs=my_applicants)
context['prev'] = prev_in_order(obj, qs=my_applicants, loop=True)
{% if prev %}
<a class="btn btn-default" href="{% url 'screening' pk=prev.id %}?{{ request.GET.urlencode }}"
aria-label="Left Align">
<span aria-hidden="true">«</span>
</a>
{% else %}
<a class="btn btn-default" href="{% url 'screening' pk=candidates.last.id %}?{{ request.GET.urlencode }}"
aria-label="Right Align">
<span aria-hidden="true">«</span>
</a>
{% endif %}
{% if next %}
<a class="btn btn-default" href="{% url 'screening' pk=next.id %}?{{ request.GET.urlencode }}"
aria-label="Left Align">
<span aria-hidden="true">»</span>
</a>
{% else %}
<a class="btn btn-default" href="{% url 'screening' pk=candidates.0.id %}?{{ request.GET.urlencode }}"
aria-label="Right Align">
<span aria-hidden="true">»</span>
</a>
{% endif %}
from django.db.models import Q
from django.db.models.sql.query import get_order_dir
def get_next_or_previous(qs, item, next=True):
"""
Get the next or previous object in the queryset, with regards to the
item specified.
"""
# If we want the previous object, reverse the default ordering
if next:
default_ordering = 'ASC'
else:
default_ordering = 'DESC'
# First, determine the ordering. This code is from get_ordering() in
# django.db.sql.compiler
if qs.query.extra_order_by:
ordering = qs.query.extra_order_by
elif not qs.query.default_ordering:
ordering = qs.query.order_by
else:
ordering = qs.query.order_by or qs.query.model._meta.ordering
assert not ordering == '?', 'This makes no sense for random ordering.'
query_filter = None
for field in ordering:
item_value = getattr(item, field)
# Account for possible reverse ordering
field, direction = get_order_dir(field, default_ordering)
# Either make sure we filter increased values or lesser values
# depending on the sort order
if direction == 'ASC':
filter_dict = {'%s__gt' % field: item_value}
else:
filter_dict = {'%s__lt' % field: item_value}
# Make sure we nicely or the conditions for the queryset
if query_filter:
query_filter = query_filter | Q(**filter_dict)
else:
query_filter = Q(**filter_dict)
# Reverse the order if we're looking for previous items
if default_ordering == 'DESC':
qs = qs.reverse()
# Filter the queryset
qs = qs.filter(query_filter)
# Return either the next/previous item or None if not existent
try:
return qs[0]
except IndexError:
return None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment