Created
March 15, 2016 10:55
-
-
Save rockymeza/ebdf13266fb6841b4c5f to your computer and use it in GitHub Desktop.
Make Django models comparable based on the Meta.ordering
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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