Frequently, when dealing with remote APIs, there's a progression of states with a definitive order and an endpoint. Often, when comparing the existing state to the proposed state, I want to make sure state is progressing in the correct direction. The stupid simple version of this is something like:
ORDER_STATES = (
('PROCESSING', _("Processing")),
('APPROVED', _("Approved")),
('PROCESSED', _("Processed")),
('SHIPPED', _("Shipped")),
('CANCELLED', _("Cancelled")),
('DECLINED', _("Card Declined")),
)
class StateIndexManager(object):
def __init__(self, states):
self.states = states
def __call__(self, value):
cp = [i[0] for i in self.states]
return cp.index(value)
state_index = StateIndexManager(ORDER_STATES)
This is obviously for a shopping cart, my arch nemesis. (Actually, every programmer's arch nemesis. Shopping carts are teh evulzh). With something like this, you can create code in a Django model that reads:
def _get_status(self):
return self.order_status
def _set_status(self, value):
if state_index(value) > state_index(self.order_status):
self.order_status = value
status = property(_get_status, _set_status)
Feel free to add a raise() in there if the state is going in the wrong direction.
I just find myself doing this often enough that having a "personal snippet" location seemed like a good idea.