Skip to content

Instantly share code, notes, and snippets.

@rockymeza
Created March 15, 2016 10:55
Show Gist options
  • Save rockymeza/ebdf13266fb6841b4c5f to your computer and use it in GitHub Desktop.
Save rockymeza/ebdf13266fb6841b4c5f to your computer and use it in GitHub Desktop.
Make Django models comparable based on the Meta.ordering
class ComparableModel(object):
"""
Make models comparable based on the Meta.ordering. Usage:
>>> import datetime
>>> class MyModel(ComparableModel, models.Model):
>>> name = models.CharField(max_length=255)
>>> birthdate = models.DateField()
>>> class Meta:
>>> app_label = 'test'
>>> ordering = ['name', '-birthdate']
>>> bob = MyModel(name='Bob', birthdate=datetime.date(1970, 1, 1))
>>> bob2 = MyModel(name='Bob', birthdate=datetime.date(2001, 1, 1))
>>> igor = MyModel(name='Igor', birthdate=datetime.date(2010, 1, 1))
>>> bob2 < bob < igor
True
"""
def __cmp__(self, other):
def cmp_tuple(field):
if field.startswith('-'):
return getattr(other, field[1:]), getattr(self, field[1:])
else:
return getattr(self, field), getattr(other, field)
# build up a list of two-tuples of values from both models, based on
# the Meta.ordering
#
# comparables = [(self.category, other.category), (self.title, other.title)]
comparables = map(cmp_tuple, self._meta.ordering)
# flatten the list of two-tuples into two lists and pass that to cmp
#
# cmp([self.category, self.name], [other.category, other.name])
return cmp(*zip(*comparables))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment