Why is django-money running incorrectly in my view?

270 views Asked by At

I'm using django-money to make conversions on my backend of the project but it is converting wrong. For example, I want to convert TRY to USD: I enter 1000000 TRY it returns 480629.66 USD, but it should be: 120055.20 USD. And when I enter 10000 Euro it returns 13677.61 USD but it should return 12139,25 USD.

How can I solve it?

views.py

def customer(request):
    form_class = NewCustomerForm
    current_user = request.user
    userP = UserProfile.objects.get_or_create(username=current_user)
    company = userP[0].company
    if request.method == 'POST':
        # Create a form instance and populate it with data from the request (binding):
        form = NewCustomerForm(request.POST)
        # Check if the form is valid:
        if form.is_valid():
            newCustomer = form.save()
            newCustomer.company = company
            selected_currency = newCustomer.currency_choice
            selected_limit = newCustomer.credit_limit
            newCustomer.usd_credit_limit = convert_money(Money(selected_limit, selected_currency), 'USD')
            cred_limit = newCustomer.usd_credit_limit
            value = str(cred_limit)[1:]
            # float_str = float(value)
            float_str = float(cred_limit.amount)
            newCustomer.credit_limit = float_str
            newCustomer.save()
            return redirect('user:customer_list')
    else:
        form = form_class()

    return render(request, 'customer.html', {'form': form})

forms.py

class NewCustomerForm(forms.ModelForm):
    ...

    class Meta:
        model = Customer
        fields = ('customer_name', 'country', 'address', 'customer_number', 'phone_number', 'email_address',
                  'credit_limit', 'currency_choice', 'risk_rating', 'parent', 'entity')

models.py

class Customer(models.Model):
...
CURRENCIES = [
        ('USD', 'USD'),
        ('EUR', 'EUR'),
        ('GBP', 'GBP'),
        ('CAD', 'CAD'),
        ('CHF', 'CHF'),
        ('DKK', 'DKK'),
        ('PLN', 'PLN'),
        ('HUF', 'HUF'),
        ('CZK', 'CZK'),
        ('RUB', 'RUB'),
        ('KZT', 'KZT'),
        ('BGN', 'BGN'),
        ('RON', 'RON'),
        ('UAH', 'UAH'),
        ('TRY', 'TRY'),
        ('ZAR', 'ZAR'),
    ]
....
 currency_choice = models.TextField(max_length=50, default='Select', choices=CURRENCIES)
 credit_limit = models.FloatField(default=0, null=True)
 usd_credit_limit = MoneyField(max_digits=14, decimal_places=2, default_currency='USD', null=True, default=0)
 risk_rating = models.CharField(max_length=50, default='Medium Risk', choices=RISK_RATING, null=True)
    ....

settings.py

OPEN_EXCHANGE_RATES_APP_ID = '.....9'
FIXER_ACCESS_KEY = '....3'

EXCHANGE_BACKEND = 'djmoney.contrib.exchange.backends.FixerBackend'
CURRENCIES = ('USD', 'EUR', 'GBP', 'CAD',
              'CHF', 'DKK', 'KZT', 'BGN',
              'PLN', 'HUF', 'CZK', 'RUB',
              'RON', 'UAH', 'TRY', 'ZAR')
OPEN_EXCHANGE_RATES_URL = 'https://openexchangerates.org/api/historical/2017-01-01.json?symbols=EUR,NOK,SEK,CZK,USD,' \
                          'GBP,CAD,CHF,DKK,KZT,BGN,PLN,HUF,RUB,RON,UAH,TRY,ZAR '
FIXER_URL = 'http://data.fixer.io/api/2013-12-24?symbols=EUR,NOK,GBP,SEK,CZK,USD,CAD,CHF,DKK,KZT,BGN,PLN,HUF,RUB,RON,' \
            'UAH,TRY,ZAR '
2

There are 2 answers

0
notNowOnlyCoding On BEST ANSWER

You are using 2017/01/01 exchange rates. Read the api link carefully. You should update your exchange rates.

    from djmoney.contrib.exchange.backends import FixerBackend, OpenExchangeRatesBackend
    from djmoney.contrib.exchange.models import get_rate
    OpenExchangeRatesBackend().update_rates()
    FixerBackend().update_rates()
    get_rate('USD', 'EUR', backend=OpenExchangeRatesBackend.name)
    get_rate('USD', 'EUR', backend=FixerBackend.name)

or you can update like :

    $ python manage.py update_rates
    Successfully updated rates from openexchangerates.org
    $ python manage.py clear_rates
    Successfully cleared rates for openexchangerates.org

You can also access the exchange rates on the admin page in default.

0
Super Kai - Kazuya Ito On

First, you need to remove OPEN_EXCHANGE_RATES_URL and FIXER_URL because Django uses the old exchange rates of 2017-01-01 and 2013-12-24 defined in OPEN_EXCHANGE_RATES_URL and FIXER_URL respectively as shown below:

"settings.py"

OPEN_EXCHANGE_RATES_APP_ID = '.....9'
FIXER_ACCESS_KEY = '....3'

EXCHANGE_BACKEND = 'djmoney.contrib.exchange.backends.FixerBackend'
CURRENCIES = ('USD', 'EUR', 'GBP', 'CAD',
              'CHF', 'DKK', 'KZT', 'BGN',
              'PLN', 'HUF', 'CZK', 'RUB',
              'RON', 'UAH', 'TRY', 'ZAR')
# OPEN_EXCHANGE_RATES_URL = '.../2017-01-01.json?...'
# FIXER_URL = '.../2013-12-24?...' # ↑ Here
                     # ↑ Here

Then, you need to run the command below to use the latest exchange rates. *Be careful, if you don't remove OPEN_EXCHANGE_RATES_URL and FIXER_URL then run the command below, the old exchange rates of 2017-01-01 and 2013-12-24 are used:

python manage.py update_rates