获取不同币种的用户钱包总余额的最佳方式是什么?
myapp/models.py
from django.db import models
from django.contrib.auth.models import User
USD = 'USD'
EUR = 'EUR'
GBP = 'GBP'
CURRENCY_CHOICES = (
(USD, 'US Dollars'),
(EUR, 'Euro'),
(GBP, 'UK Pounds'),
)
class Wallet(models.Model):
user = models.ForeignKey(User)
accnumber = models.CharField(max_length=12)
currency = models.CharField(choices=CURRENCY_CHOICES, default=EUR)
balance = models.DecimalField(max_digits=9,decimal_places=2)
汇率从 fixer.io 获得以字典形式
[(u'usd', '美元'), (u'eur', '欧元'), (u'rub', '俄罗斯卢布'), (u'gbp', '英国英镑' ), (u'btc', '比特币'), (u'eth', '以太坊')]
myapp/views.py
import requests
from decimal import Decimal
from django.conf import settings
from django.views.generic.base import TemplateView
from django.db.models import Sum
from myyapp.model import Wallet, CURRENCY_CHOICES
class TotalBalanceView(TemplateView):
template_name = 'balance.html'
def get_context_data(self, **kwargs):
context = super(TotalBalanceView, self).get_context_data(**kwargs)
#get current exchage rates from Fixer.IO
symbols = ','.join(dict(CURRENCY_CHOICES).keys()).upper()
uri = "http://data.fixer.io/api/latest?access_key={}&base=EUR&symbols={}".format(FIXER_API, symbols)
r = requests.get(uri)
rates = r.json()['rates']
#get account for the user
wallets = Wallet.objects.filter(user=self.request.user)
total = Decimal()
for curr in CURRENCY_CHOICES:
total += wallets.filter(currency=curr).aggregate(
total=Sum('balance'))
context.update({
'wallets ': wallets
'total': total_eur + total_usd * rates['USD'] + total_gbp * rates['GBP']
})
return context
myapp/templates/balance.html
<h1>Total is: {{ total|floatformat:2 }}</h1>
{% for w in wallets %}
<p>{{ w.accnumber }}</p>
{% endfor %}
我确信应该有更有效的解决方案在一个查询请求中使用聚合函数
最佳答案
我们基本上可以通过按货币执行某种分组来做到这一点:
totals = (wallets.values('currency')
.annotate(total=Sum('balance'))
.order_by('currency'))
这将产生字典的可迭代,其中currency
映射到货币,以及映射的total
到该货币的总额。例如:
[{'currency': 'EUR', 'total': 123.45},
{'currency': 'USD', 'total': 456.78},
{'currency': 'BFR', 'total': 901.23}]
然后我们可以计算一种货币的总计:
total = sum([subsum[total] * rate[subsum['currency']]
for subsum in totals])
您可能需要为要转换的货币添加汇率(汇率等于1.00
)。
关于Django查询不同币种钱包的总余额,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50739195/