如果"类别名称"是唯一的,有没有一种方法可以在HTML中的一行中获得所有金额?根据我的代码,"类别名称"不再是唯一的,因为它是按月份注释的.谢谢你

生效日期:

enter image description here

HTML输出:我希望他们都在一行,因为他们是"汽车支付"

enter image description here

Views.py

class CashFlow(LoginRequiredMixin, AccountContextMixin, TemplateView):
    model = Transaction
    template_name = 'transaction_app/cf.html'
    context_object_name = 'transaction'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user

        #-------Dropdown Begins---------
        #Get unique years for dropdown
        distinct_years = Transaction.objects.filter(user=user).dates('transaction_date', 'year')
        year_choices = [(date.year, date.year) for date in distinct_years]
        unique_years = list(set(year_choices))
        unique_years.sort()
        context['unique_years'] = unique_years
        #-------Dropdown Ends-----------

        #---Get Data From Dropdown Begins---------       
        selected_year = self.request.GET.get('selected_year')
        selected_year = int(selected_year) if selected_year else datetime.now().year
    
        selected_status = self.request.GET.get('selected_status')
        #---Get Data From Dropdown Ends-----------

        #----Get Data for Table Begins------------
        
        # Obtain distinct category names
        category_names = Transaction.objects.filter(
            user=user,
            transaction_date__year=selected_year,
            status=selected_status
        ).values_list('category__category_name', flat=True).distinct()

        # Aggregate data for each distinct category
        category_sums = []
        for category_name in category_names:
        # Aggregate total amount for each month within the specified year for the current category
            category_sum_by_month = Transaction.objects.filter(
                user=user,
                transaction_date__year=selected_year,
                status=selected_status,
                category__category_name=category_name
            ).annotate(
                month=ExtractMonth('transaction_date')
            ).values('month').annotate(
                total_amount=Sum('amount')
            )

            # Append category name and its monthly sums to category_sums list
            for item in category_sum_by_month:
                item['category__category_name'] = category_name
                category_sums.append(item)

            # Aggregate total amount for the current category
            category_sum = Transaction.objects.filter(
                user=user,
                transaction_date__year=selected_year,
                status=selected_status,
                category__category_name=category_name
            ).aggregate(
                total_amount=Sum('amount')
            )

            category_sum['category__category_name'] = category_name
            category_sums.append(category_sum)
            category_sums.append(category_sum_by_month)

            context['category_sums'] = category_sums
        #----Get Data for Table Begins------------
        return context

Html template

<table class="tbl-big" border="1">
    <thead>
        <tr>
            <th>Category Name</th>
            <th>Jan</th>
            <th>Feb</th>
            <th>Mar</th>
            <th>Total</th>
        </tr>
    </thead>
    <tbody>
        {% for item in category_sums %}
        <tr>
            <td>{{item.category__category_name}}</td>
            
            <td>
            {% if item.month == 1%}
            {{item.total_amount}}
            {% endif %}
            </td>
            
            <td>
            {% if item.month == 2%}
            {{item.total_amount}}
            {% endif %}
            </td>

            <td>
            {% if item.month == 3%}
            {{item.total_amount}}
            {% endif %}
            </td>

            <td>{{item.total_amount}}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

数据输出:

{'month': 1, 'total_amount': Decimal('-1400.03000000000'),
'category__category_name': 'Car Payment'} {'month': 2, 'total_amount':
Decimal('-1400.03000000000'), 'category__category_name': 'Car
Payment'} {'total_amount': Decimal('-2800.06000000000'),
'category__category_name': 'Car Payment'} <QuerySet [{'month': 1,
'total_amount': Decimal('-1400.03000000000'),
'category__category_name': 'Car Payment'}, {'month': 2,
'total_amount': Decimal('-1400.03000000000'),
'category__category_name': 'Car Payment'}]>

解决方案:感谢@ willeM_Van Onsem

CategoryOverview = namedtuple('CategoryOverview', ['name', 'entries', 'total'])

class CashFlow(LoginRequiredMixin, AccountContextMixin, TemplateView):
    model = Transaction
    template_name = 'transaction_app/cf.html'
    context_object_name = 'transaction'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = self.request.user

...

        items = defaultdict(dict)
        sum_per_month = (
            Transaction.objects.filter(
                user=user,
                transaction_date__year=selected_year,
                status=selected_status,
            )
            .values(
                month=ExtractMonth('transaction_date'),
                category_name=F('category__category_name'),
            )
            .annotate(total_amount=Sum('amount'))
            .order_by('category_name', 'month')
        )

        for record in sum_per_month:
            items[record['category_name']][record['month']] = record['total_amount']
        
        context['summary'] = [
            CategoryOverview(key, [entries.get(month) for month in range(1, 13)], sum(entries)
            )
            for key, entries in items.items()
        ]

        return context

推荐答案

我认为这里的主要问题是应该以可访问的方式提供数据的视图.我们可以使用:

from collections import Counter, defaultdict, namedtuple

CategoryOverview = namedtuple('CategoryOverview', ['name', 'entries', 'total'])


class CashFlow(LoginRequiredMixin, AccountContextMixin, TemplateView):
    model = Transaction
    template_name = 'transaction_app/cf.html'
    context_object_name = 'transaction'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        selected_year = self.request.GET.get('selected_year')
        selected_year = (
            int(selected_year) if selected_year else datetime.now().year
        )
        items = defaultdict(dict)
        sum_per_month = (
            Transaction.objects.filter(
                user=user,
                transaction_date__year=selected_year,
                status=selected_status,
            )
            .values(
                month=ExtractMonth('transaction_date'),
                category_name=F('category__category_name'),
            )
            .annotate(total_amount=Sum('amount'))
            .order_by('category_name', 'month')
        )
        for record in sum_per_month:
            items[record['category_name']][record['month']] = record['total']
        context['summary'] = [
            CategorySummary(
                key, [entries.get(month) for month in range(1, 12)], sum(entries)
            )
            for key, entries in items.items()
        ]
        return context

那么我们就可以很容易地用

<table class="tbl-big" border="1">
    <thead>
        <tr>
            <th>Category Name</th>
            <th>Jan</th>
            <th>Feb</th>
            <th>Mar</th>
            <th>Apr</th>
            <th>May</th>
            <th>Jun</th>
            <th>Jul</th>
            <th>Aug</th>
            <th>Sep</th>
            <th>Oct</th>
            <th>Nov</th>
            <th>Dec</th>
            <th>Sep</th>
            <th>Total</th>
        </tr>
    </thead>
    <tbody>
        {% for category in summary %}
        <tr>
            <td>{{category.name }}</td>
            
            {% for entry in category.entries %}<td>{{ entry }}</td>{% endfor %}
            <td>{{ item.total }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

这也将提高效率,因为我们执行one来获取所有事务,然后简单地按类别分类.

Python相关问答推荐

使用Keras的线性回归参数估计

如何自动抓取以下CSV

如何计算两极打印机中 * 所有列 * 的出现次数?

try 与gemini-pro进行多轮聊天时出错

点到面的Y距离

如何在箱形图中添加绘制线的传奇?

对所有子图应用相同的轴格式

OR—Tools中CP—SAT求解器的IntVar设置值

将9个3x3矩阵按特定顺序排列成9x9矩阵

将输入聚合到统一词典中

计算每个IP的平均值

根据列值添加时区

在matplotlib中删除子图之间的间隙_mosaic

为什么np. exp(1000)给出溢出警告,而np. exp(—100000)没有给出下溢警告?

如何在海上配对图中使某些标记周围的黑色边框

在Docker容器(Alpine)上运行的Python应用程序中读取. accdb数据库

Js的查询结果可以在PC Chrome上显示,但不能在Android Chrome、OPERA和EDGE上显示,而两者都可以在Firefox上运行

在round函数中使用列值

Polars时间戳同步延迟计算

我如何为测试函数的参数化提供fixture 生成的数据?如果我可以的话,还有其他 Select 吗?