Skip to content

Instantly share code, notes, and snippets.

@drdaeman
Last active May 12, 2016 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drdaeman/5d1a948e829ceb78af7afce701378545 to your computer and use it in GitHub Desktop.
Save drdaeman/5d1a948e829ceb78af7afce701378545 to your computer and use it in GitHub Desktop.
Experiment with django-money to have multiple money fields that share the single currency. May contain bugs, use with extreme caution.
from __future__ import absolute_import, unicode_literals
from djmoney.models.fields import MoneyField, MoneyFieldProxy
class CurrencyLockedMoneyFieldProxy(MoneyFieldProxy):
def __init__(self, field, currency_field_name=None):
super(CurrencyLockedMoneyFieldProxy, self).__init__(field)
if currency_field_name is not None:
self.currency_field_name = currency_field_name
def __set__(self, obj, value):
obj_curr = obj.__dict__[self.currency_field_name]
val_curr = str(value.currency)
if obj_curr is None:
obj_curr = str(self.field.default_currency)
if obj_curr is not None and obj_curr != val_curr:
raise ValueError(
"Incompatible currencies: %s vs %s" % (val_curr, obj_curr)
)
return super(CurrencyLockedMoneyFieldProxy, self).__set__(obj, value)
class MoneyAmountField(MoneyField):
def __init__(self, *args, **kwargs):
self.currency_field_name = kwargs.pop("currency_field_name", None)
super(MoneyAmountField, self).__init__(*args, **kwargs)
def contribute_to_class(self, cls, name):
proxy = CurrencyLockedMoneyFieldProxy(self, self.currency_field_name)
super(MoneyField, self).contribute_to_class(cls, name)
setattr(cls, self.name, proxy)
def deconstruct(self):
name, path, args, kwargs = super(MoneyAmountField, self).deconstruct()
kwargs["currency_field_name"] = self.currency_field_name
return name, path, args, kwargs
# Django <=1.6: Haven't checked if South would work without changes or not.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment