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

make utils.py work with cached queryset results dict #80

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions currencies/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from jsonfield.fields import JSONField
from django.core.cache import cache

from .managers import CurrencyManager

Expand Down Expand Up @@ -53,4 +54,7 @@ def save(self, **kwargs):
if self.is_default or self.is_base:
self.is_active = True

cache_key = 'django-currencies-active'
cache.delete(cache_key)

super(Currency, self).save(**kwargs)
67 changes: 53 additions & 14 deletions currencies/utils.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
# -*- coding: utf-8 -*-
from decimal import Decimal as D, InvalidOperation, ROUND_UP
from django.forms.models import model_to_dict
from django.core.cache import cache

from .models import Currency as C
from .conf import SESSION_KEY


def get_active_currencies_qs():
return C.active.defer('info').all()


def calculate(price, to_code, **kwargs):
"""Converts a price in the default currency to another currency"""
qs = kwargs.get('qs', get_active_currencies_qs())
kwargs['qs'] = qs
default_code = qs.default().code
# qs = kwargs.get('qs', get_active_currencies_qs())
# kwargs['qs'] = qs
# default_code = qs.default().code
default_code = get_default_currency()['code']
return convert(price, default_code, to_code, **kwargs)


def convert(amount, from_code, to_code, decimals=2, qs=None):
def convert(amount, from_code, to_code, decimals=2,):
"""Converts from any currency to any currency"""
if from_code == to_code:
return amount

if qs is None:
qs = get_active_currencies_qs()
# if qs is None:
# qs = get_active_currencies_qs()

qs = get_currencies_dict()

from_, to = qs.get(code=from_code), qs.get(code=to_code)
# from_, to = qs.get(code=from_code), qs.get(code=to_code)
from_, to = qs[from_code], qs[to_code]

amount = D(amount) * (to.factor / from_.factor)
# amount = D(amount) * (to.factor / from_.factor)
amount = D(amount) * (to['factor'] / from_['factor'])
return price_rounding(amount, decimals=decimals)


Expand All @@ -39,10 +45,11 @@ def get_currency_code(request):
continue

# fallback to default...
try:
return C.active.default().code
except C.DoesNotExist:
return None # shit happens...
# try:
# return C.active.default().code
# except C.DoesNotExist:
# return None # shit happens...
return get_default_currency()['code']


def price_rounding(price, decimals=2):
Expand All @@ -53,3 +60,35 @@ def price_rounding(price, decimals=2):
# Currencies with no decimal places, ex. JPY, HUF
exponent = D()
return price.quantize(exponent, rounding=ROUND_UP)


def get_default_currency():
currencies = get_currencies_dict()
for code, cur in currencies.items():
if cur['is_default']:
return cur
return None # shit happens...


def get_currencies_dict():
cache_key = 'django-currencies-active'
result = cache.get(cache_key)
if result is None:
# print('--- --- cache not found, DB iterating.....')

qs = C.active.defer('info').all()

result = {}
for cur in qs:
result[cur.code] = model_to_dict(cur, fields=('code','name','symbol','factor','is_base','is_default',))

cache.set(cache_key, result, 3600 * 1) # 1 Hour (This cache var unset on every model change)

# print('--- get_currencies_dict() result =', result)

return result


def get_active_currencies_qs():
return C.active.defer('info').all()