Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically set currency #11

Open
derenio opened this issue Jul 1, 2013 · 5 comments
Open

Dynamically set currency #11

derenio opened this issue Jul 1, 2013 · 5 comments

Comments

@derenio
Copy link
Contributor

derenio commented Jul 1, 2013

One of our projects requires the currency of the PriceField to be dynamically set.
Our solution is to define get_currency method on the PriceField which can be overridden by class inheritance.
master...derenio:feature/dynamic_currency

Exemplary use case:

from django.db import models
from django_prices.models import PriceField


class DynamicPriceField(PriceField):

    def get_currency(self):
        if not self.currency:
            self.currency = self.model.currency
        return self.currency

class Purchase(models.Model):
    CURRENCY_CHOICES = [
        ('USD', 'USD'),
        ('GBP', 'GBP'),
        ('PLN', 'PLN')]

    currency = models.ChoiceField(choices=CURRENCY_CHOICES)
    price =     cost = DynamicPriceField(decimal_places=2, max_digits=10, default=Decimal())
@patrys
Copy link
Contributor

patrys commented Jul 1, 2013

I'd rather create a PriceAndCurrencyField that stores the currency in a database field.

@derenio
Copy link
Contributor Author

derenio commented Oct 10, 2013

Django still doesn't support the multiple db columns field:
https://code.djangoproject.com/ticket/5929
We will have to let programmers manually define the currency field and provide its name as a constructor's parameter in the price field.

@spout
Copy link

spout commented Jul 20, 2015

@derenio: same issue, so I've tried your example. I get Price instance without currency (Price('10', currency=None)).
(Using django-prices with django-prices-openexchangerates)

@derenio
Copy link
Contributor Author

derenio commented Jul 22, 2015

@spout my exemplary use case was based on my feature branch master...derenio:feature/dynamic_currency.
If you want to be able to have the currency based on a custom field (retrieved in the get_currency method) you will also have to override the changed to_python and formfield methods in the DynamicPriceField class (change self.currency to self.get_currency()):

class DynamicPriceField(PriceField):

    def get_currency(self):
        if not self.currency:
            self.currency = self.model.currency
        return self.currency

    def to_python(self, value):
        currency = self.get_currency()
        if isinstance(value, Price):
            if value.currency != currency:
                raise ValueError('Invalid currency: %r (expected %r)' % (
                    value.currency, currency))
            return value
        value = super(PriceField, self).to_python(value)
        if value is None:
            return value
        return Price(value, currency=currency)

    def formfield(self, **kwargs):
        defaults = {'currency': self.get_currency(),
                    'form_class': forms.PriceField}
        defaults.update(kwargs)
        return super(PriceField, self).formfield(**defaults)

@spout
Copy link

spout commented Jul 22, 2015

@derenio: Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants