I want to convert currencies in my Django app. I created a model Customer
. In customer model, there are two fields for that credit_limit
and currency_choice
. I am using django-money for conversion. But I get an error:
MissingRate at /customer Rate GBP -> USD does not exist
How can I solve it?
views.py:
from djmoney.money import Money from djmoney.contrib.exchange.models import convert_money 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': form = NewCustomerForm(request.POST) if form.is_valid(): newCustomer = form.save() newCustomer.company = company selected_currency = newCustomer.currency_choice selected_limit = newCustomer.credit_limit value = Money(selected_limit, selected_currency) converted = convert_money(value, 'USD') print(converted) newCustomer.save() return redirect('user:customer_list') else: form = form_class() return render(request, 'customer.html', {'form': form})
models.py:
class Customer(models.Model): ... CURRENCIES = [ ('USD', 'USD'), ('EUR', 'EUR'), ('GBP', 'GBP'), ] ... credit_limit = models.FloatField(default=0) currency_choice = models.TextField(max_length=50, default='Select', choices=CURRENCIES)
settings.py:
... INSTALLED_APPS = [ ..., 'djmoney', ... ] ... EXCHANGE_BACKEND = 'djmoney.contrib.exchange.backends.FixerBackend' CURRENCIES = ('USD', 'EUR', 'GBP') OPEN_EXCHANGE_RATES_URL = 'https://openexchangerates.org/api/historical/2017-01-01.json?symbols=EUR,NOK,SEK,CZK,USD,GBP' FIXER_URL = 'http://data.fixer.io/api/2013-12-24?symbols=EUR,NOK,GBP,SEK,CZK,USD,GBP'
traceback:
Environment: Request Method: POST Request URL: http://127.0.0.1:8000/customer Django Version: 3.1.4 Python Version: 3.8.8 Installed Applications: ['django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'register', 'customer', 'financial_analysis', 'ocr', 'core', 'approvals', 'crispy_forms', 'ckeditor', 'rest_framework', 'requests', 'ckeditor_uploader', 'django_filters', 'activity_log', 'djmoney', 'djmoney.contrib.exchange'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware'] Traceback (most recent call last): File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersexception.py", line 47, in inner response = get_response(request) File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjangocorehandlersbase.py", line 179, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "C:UsersUSEROneDriveDocumentsGitHubotccustomerviews.py", line 27, in customer newCustomer.usd_credit_limit = convert_money(Money(selected_limit, selected_currency), 'USD') File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjmoneycontribexchangemodels.py", line 108, in convert_money amount = value.amount * get_rate(value.currency, currency) File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjmoneycontribexchangemodels.py", line 49, in get_rate result = _get_rate(source, target, backend) File "C:UsersUSEROneDriveDocumentsGitHubotcmyvenvlibsite-packagesdjmoneycontribexchangemodels.py", line 60, in _get_rate raise MissingRate("Rate %s -> %s does not exist" % (source, target)) Exception Type: MissingRate at /customer Exception Value: Rate BGN -> USD does not exist
Advertisement
Answer
I took a quick look at the code that’s rising exceptions. If you take a closer look at line 60 here:
that’s the error that’s being raised. 2 lines above you can see a queryset that triggers this error:
rates = Rate.objects.filter(currency__in=(source, target), backend=backend).select_related("backend")
I have then noticed that there’s a management command that creates these Rate objects:
it seems that you can use the following command:
./manage.py update_rates
does this help?