Django按起止日期筛选数据并模板展示报错求助
问题分析与解决方案
错误原因
- 表单字段类型误用:使用
ModelChoiceField但传入的queryset是日期值列表而非Income模型实例,导致表单验证时无法匹配有效选项,触发"Select a valid choice..."错误。 - 日期转换逻辑错误:试图用
datetime(selectedDate1)直接将date对象转换为datetime,datetime构造函数不支持该传参方式,会引发类型错误,导致筛选逻辑失效,始终返回全部数据。 - 错误反馈缺失:表单验证失败时直接返回全部数据,未保留错误信息,无法直观排查问题。
修复步骤
1. 修正表单字段定义(forms.py)
替换ModelChoiceField为适合日期选择的字段,以下两种方案可选:
方案一:灵活选择任意日期(DateField)
from django import forms from .models import Income class DateChoiceField(forms.Form): date1 = forms.DateField(label='起始日期', widget=forms.SelectDateWidget) date2 = forms.DateField(label='结束日期', widget=forms.SelectDateWidget)
方案二:仅允许选择数据库中已存在的日期(ChoiceField)
from django import forms from .models import Income # 提取数据库中唯一日期并转换为表单选项格式 date_options = [(d.strftime('%Y-%m-%d'), d) for d in Income.objects.values_list('date', flat=True).distinct().order_by('date')] class DateChoiceField(forms.Form): date1 = forms.ChoiceField(label='起始日期', choices=date_options) date2 = forms.ChoiceField(label='结束日期', choices=date_options)
2. 优化视图筛选逻辑(views.py)
修复日期转换错误,调整表单验证流程:
from django.shortcuts import render from .forms import DateChoiceField from .models import Income def dashboard(request): filterYearMonth = Income.objects.all() form = DateChoiceField() if request.method == "POST" and 'form1' in request.POST: form = DateChoiceField(request.POST) if form.is_valid(): selected_date1 = form.cleaned_data["date1"] selected_date2 = form.cleaned_data["date2"] # 直接使用date对象筛选,无需转换为datetime filterYearMonth = Income.objects.filter(date__gte=selected_date1, date__lte=selected_date2) context = { 'filterYearMonth': filterYearMonth, 'form': form, } return render(request, "dashboard/dashboard.html", context)
3. 模板添加错误提示与空数据反馈(dashboard.html)
<form method="POST" action="/dashboard/"> {% csrf_token %} <!-- 显示表单全局错误 --> {% if form.non_field_errors %} <div style="color: red;">{{ form.non_field_errors }}</div> {% endif %} <!-- 显示单个字段错误 --> <div> {{ form.date1.label_tag }} {{ form.date1 }} {% if form.date1.errors %} <span style="color: red;">{{ form.date1.errors.0 }}</span> {% endif %} </div> <div> {{ form.date2.label_tag }} {{ form.date2 }} {% if form.date2.errors %} <span style="color: red;">{{ form.date2.errors.0 }}</span> {% endif %} </div> <button type="submit" name="form1">Submit</button> </form> <h4>Filter</h4> <table> {% for item in filterYearMonth %} <tr> <td>{{ item.date }}</td> <td>{{ item.capital }}</td> <td>{{ item.revenue }}</td> <td>{{ item.profit }}</td> </tr> {% empty %} <tr> <td colspan="4">无匹配数据</td> </tr> {% endfor %} </table>
内容的提问来源于stack exchange,提问作者Kira Yoshikage
相关产品推荐
相关产品推荐

