Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Sortation utilities are separated from the ``SortedModel`` in order to keep the model clean and prevent possible
3collisions or conflicts with method names.
5They may still be used in a declarative manner, for example:
7.. code-block:: python
9 from superdjango.db.sorted import utils as sortation
10 from .models import Task
12 task = Task.objects.get(pk=1234)
14 if sortation.has_previous_record(task):
15 previous_task = sortation.get_previous_record(task)
17 if sortation.has_next_record(task):
18 next_task = sortation.get_next_record(task)
20"""
22# Exports
24__all__ = (
25 "get_next_record",
26 "get_previous_record",
27 "has_next_record",
28 "has_previous_record",
29 "is_sortable",
30)
32# Functions
35def get_previous_record(instance, **criteria):
36 """Get the previous record, if one exists.
38 :param instance: The instance to be checked.
40 :param criteria: Additional criteria to be given. This is useful when
41 the record is embedded in a hierarchy.
42 :type criteria: dict
44 :rtype: models.Model
45 :returns: Returns the previous instance or ``None`` if a previous instance
46 could not be found.
48 """
49 if not is_sortable(instance):
50 return None
52 cls = instance.__class__
54 fn = "sort_order"
55 try:
56 criteria['%s__lt' % fn] = instance.sort_order
57 return cls.objects.filter(**criteria).order_by("-%s" % fn)[0]
58 except IndexError:
59 return None
62def get_next_record(instance, **criteria):
63 """Get the next record, if one exists.
65 :param instance: The instance to be checked.
67 :param criteria: Additional criteria to be given. This is useful when
68 the record is embedded in a hierarchy.
69 :type criteria: dict
71 :rtype: models.Model
72 :returns: Returns the next instance or ``None`` if a next instance
73 could not be found.
75 """
76 if not is_sortable(instance):
77 return None
79 cls = instance.__class__
81 fn = "sort_order"
82 try:
83 criteria['%s__gt' % fn] = instance.sort_order
84 return cls.objects.filter(**criteria).order_by("-%s" % fn)[0]
85 except IndexError:
86 return None
89def has_next_record(instance, **criteria):
90 """Indicates whether a record exists with a higher sort order.
92 :param instance: The instance to be checked.
94 :param criteria: Additional criteria to be given. This is useful when
95 the record is embedded in a hierarchy.
96 :type criteria: dict
98 :rtype: bool
100 """
101 cls = instance.__class__
102 fn = "sort_order"
104 criteria['%s__gt' % fn] = instance.sort_order
105 return cls.objects.filter(**criteria).count() > 0
108def has_previous_record(instance, **criteria):
109 """Indicates whether a record exists with a lower sort order.
111 :param instance: The instance to be checked.
113 :param criteria: Additional criteria to be given. This is useful when
114 the record is embedded in a hierarchy.
115 :type criteria: dict
117 :rtype: bool
119 """
120 cls = instance.__class__
121 fn = "sort_order"
123 criteria['%s__lt' % fn] = instance.sort_order
124 return cls.objects.filter(**criteria).count() > 0
127def is_sortable(instance):
128 """Determine whether a given instance is sortable.
130 :param instance: The instance to be checked.
131 :type instance: object
133 :rtype: bool
134 :returns: Returns ``True`` if the instance inherits from :py:class:`SortedModel` *or* a ``sort_order`` attribute is
135 defined on the instance.
137 """
138 # Avoid import errors.
139 from .models import SortedModel
141 if isinstance(instance, SortedModel):
142 return True
143 elif hasattr(instance, "sort_order"):
144 return True
145 else:
146 return False