diff options
| author | Simon Charette <charette.s@gmail.com> | 2012-05-07 20:08:20 +0300 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2012-05-07 20:08:20 +0300 |
| commit | 5cbfb48b92cb26a335f9c8c0f79d3390290103e2 (patch) | |
| tree | 197836116e12332cc43b62dce75af54878cb70cb /django/utils | |
| parent | 1aae1cba99b0f8232527742d64b120e4d902c68d (diff) | |
Made model fields comparable to other objects
Fixed #17851 -- Added __lt__ and @total_ordering to models.Field,
made sure these work correctly on other objects than Field, too.
Diffstat (limited to 'django/utils')
| -rw-r--r-- | django/utils/functional.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/django/utils/functional.py b/django/utils/functional.py index befe3e9dad..86bbed7a7b 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -310,3 +310,35 @@ def partition(predicate, values): for item in values: results[predicate(item)].append(item) return results + +try: + from functools import total_ordering +except ImportError: + # For Python < 2.7 + # Code borrowed from python 2.7.3 stdlib + def total_ordering(cls): + """Class decorator that fills in missing ordering methods""" + convert = { + '__lt__': [('__gt__', lambda self, other: not (self < other or self == other)), + ('__le__', lambda self, other: self < other or self == other), + ('__ge__', lambda self, other: not self < other)], + '__le__': [('__ge__', lambda self, other: not self <= other or self == other), + ('__lt__', lambda self, other: self <= other and not self == other), + ('__gt__', lambda self, other: not self <= other)], + '__gt__': [('__lt__', lambda self, other: not (self > other or self == other)), + ('__ge__', lambda self, other: self > other or self == other), + ('__le__', lambda self, other: not self > other)], + '__ge__': [('__le__', lambda self, other: (not self >= other) or self == other), + ('__gt__', lambda self, other: self >= other and not self == other), + ('__lt__', lambda self, other: not self >= other)] + } + roots = set(dir(cls)) & set(convert) + if not roots: + raise ValueError('must define at least one ordering operation: < > <= >=') + root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__ + for opname, opfunc in convert[root]: + if opname not in roots: + opfunc.__name__ = opname + opfunc.__doc__ = getattr(int, opname).__doc__ + setattr(cls, opname, opfunc) + return cls |
