You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django实现不同加密货币钱包余额汇总问题求助

解决加密货币钱包按币种分组显示收支总和的问题

看起来你需要实现的是按币种分组,计算每个币种的净收支(区分收入和支出),同时显示货币名称而非ID。咱们一步步来修复这个问题:

1. 修改Views中的查询逻辑(核心部分)

原来的wallet查询只是获取了所有交易记录,没有做分组和聚合计算。我们需要结合annotate与Case/When来精准计算每个币种的净余额,同时通过values关联Currency模型的字段来获取名称:

from django.db.models import Sum, Case, When, IntegerField, F

@login_required
def profile(request):
    # 按币种分组,计算用户的净余额:收入(user_credit)加金额,支出(user_debit)减金额
    wallet = Transaction.objects.filter(
        Q(user_credit=request.user) | Q(user_debit=request.user)
    ).values(
        # 指定关联的Currency字段,用于分组和前端显示
        'currency_id__id',
        'currency_id__currency_name',
        'currency_id__ticker'
    ).annotate(
        total_balance=Sum(
            Case(
                When(user_credit=request.user, then='exchange_amount'),
                When(user_debit=request.user, then=-F('exchange_amount')),
                default=0,
                output_field=IntegerField()
            )
        )
    ).order_by('-currency_id__currency_name')  # 按货币名称排序,可选

    transactions = Transaction.objects.filter(
        Q(user_credit=request.user) | Q(user_debit=request.user)
    ).order_by('-created_at')[:10]
    
    listings = Listing.objects.filter(user=request.user).order_by('-created_at')[:10]
    
    args = {'wallets': wallet, 'transactions': transactions, 'listings': listings}
    return render(request, 'profile.html', args)

代码说明:

  • values()中指定Currency的字段,让Django按这些字段分组,同时把名称、代号等信息带回结果
  • Case/When逻辑区分用户是交易的收入方还是支出方,正确计算净余额(收入加金额,支出减金额)
  • annotate(total_balance=...)完成每个币种的余额聚合计算

2. 修复模板中的显示逻辑

现在前端可以直接访问分组后的货币名称和总余额了,修改钱包区域的代码:

<div class="col-md-4">
<h2>My wallet</h2>
{% if wallets %}
<ul class=list-unstyled >
{% for wallet in wallets %}
<li>{{ wallet.currency_id__currency_name }} ({{ wallet.currency_id__ticker }}): {{ wallet.total_balance|floatformat:"2" }}</li>
{% endfor %}
</ul>
{% else %}
<p>No currencies in your wallet yet.</p>
{% endif %}
</div>

顺手修复模板小错误:

你模板里的<pan style="font-style: italic">应该是<span>,可以调整成:

<p>Username is <span style="font-style: italic">{{ user.username }}</span> and joined SolvayCoin {{ user.date_joined|timesince }} ago</p>

为什么之前只显示ID?

你之前尝试sum和annotate却只拿到ID,是因为没有在values()中指定关联的Currency字段——Django默认只会按外键ID分组,不会自动关联获取名称。通过在values()里加入currency_id__currency_name,我们既完成了分组逻辑,又能在结果中拿到所需的货币名称。

内容的提问来源于stack exchange,提问作者user9758616

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:08:20