Django费用追踪App:页面跳转传递日期筛选条件的实现问题
解决方案
针对你提出的两个问题,以下是具体的实现步骤:
1. 让目标视图获取X天筛选条件
要让目标视图拿到原页面的X天参数,核心是把num_of_days作为URL的一部分传递,同时在视图函数中接收这个参数。具体操作如下:
步骤1:配置新的URL规则
在你的urls.py中添加一条包含num_of_days和分类标识的URL:
from django.urls import path from . import views app_name = 'expenses' urlpatterns = [ path('<int:num_of_days>days/', views.last_xdays, name='last_xdays'), # 新增URL:匹配/expenses/30days/travel/这类路径 path('<int:num_of_days>days/<slug:category_slug>/', views.category_subcategory_summary, name='category_subcategory'), ]
步骤2:编写目标视图函数
创建category_subcategory_summary视图,接收num_of_days和category_slug参数,按条件统计子分类费用:
from django.db.models import Sum, Q from django.shortcuts import render, get_object_or_404 from datetime import date, timedelta from .models import Categories, SubCategories, Transaction def category_subcategory_summary(request, num_of_days, category_slug): # 按slug获取分类(建议给Categories模型添加slug字段,避免名称特殊字符问题) category = get_object_or_404(Categories, slug=category_slug) # 计算时间范围 start_date = date.today() - timedelta(days=num_of_days) end_date = date.today() # 统计该分类下最近X天各子分类的总费用 subcategory_list = SubCategories.objects.filter(category=category).annotate( sub_total=Sum('subcategory__amount', filter=Q( subcategory__transaction_date__gte=start_date, subcategory__transaction_date__lte=end_date )) ).filter(sub_total__gt=0) # 只显示有费用的子分类 return render(request, 'expenses/category_detail.html', { 'category': category, 'num_of_days': num_of_days, 'subcategory_list': subcategory_list })
补充:给Categories模型添加slug字段的规范写法:
from django.utils.text import slugify class Categories(models.Model): category_text = models.CharField(max_length=50) slug = models.SlugField(unique=True, blank=True) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.category_text) super().save(*args, **kwargs) def __str__(self): return self.category_text
2. 构造包含X天参数与分类名称的URL
要生成/expenses/30days/Travel这类URL,需要在模板中同时传递num_of_days和分类标识,具体操作:
步骤1:在原视图中传递num_of_days到模板
修改last_xdays视图,把num_of_days加入上下文:
def last_xdays(request, num_of_days): last_xdays_date = date.today() - timedelta(days=num_of_days) transaction_list = Transaction.objects.filter( transaction_date__gte=last_xdays_date, transaction_date__lte=date.today() ) if not transaction_list: raise Http404("No transactions found.") category_list = Categories.objects.annotate( category_sum=Sum('category__subcategory__amount', filter=Q(category__subcategory__transaction_date__gte=last_xdays_date, category__subcategory__transaction_date__lte=date.today())) ).filter(category_sum__gt=0) # 新增:把num_of_days传递给模板 return render(request, 'expenses/index.html', { 'category_list': category_list, 'transaction_list': transaction_list, 'num_of_days': num_of_days })
步骤2:在模板中生成目标URL
修改模板中的链接,使用url标签同时传入num_of_days和分类slug:
{% for category in category_list %} <tr> <td> <a href="{% url 'expenses:category_subcategory' num_of_days category.slug %}"> {{ category.category_text }} </a> </td> <td>{{ category.category_sum }}</td> </tr> {% endfor %}
这样点击分类链接时,就会跳转到包含X天参数和分类标识的URL,目标视图也能通过参数获取筛选条件,进而统计对应子分类的费用总和。
内容的提问来源于stack exchange,提问作者Ravi Ahuja
相关产品推荐
相关产品推荐

