【问题标题】:How to change dates when filtering a queryset in Django?在 Django 中过滤查询集时如何更改日期?
【发布时间】:2025-12-08 15:05:02
【问题描述】:

我想显示公司完成的所有付款的清单。但我希望能够过滤日期,例如仅显示付款:

  • 过去 30 天
  • 过去 90 天
  • 在两个特定日期之间

现在,我知道我可以在两个日期之间或今天之前过滤我的视图。 但是我如何使用模板上的下拉菜单或数据选择器来做到这一点?

这样的东西供参考。

作为参考,付款模式如下:

class Payment(models.Model):
    name = models.CharField(max_length=250)
    date = models.DateField(default=datetime.now)
    value = models.DecimalField(max_digits=10, decimal_places=2, validators=[MinValueValidator(0.00)])

【问题讨论】:

    标签: python django


    【解决方案1】:

    使用带有选择字段的 django 表单并根据您的查询集的值过滤器。例如:

    选择:

    PERIOD_LAST_THREE_MONTHS = "last-three-months"
    PERIOD_LAST_SIX_MONTHS = "last-six-months" # ..
    
    PERIOD_CHOICES = (
        (PERIOD_LAST_THREE_MONTHS, _("Last 3 Months")),
        (PERIOD_LAST_SIX_MONTHS, _("Last 6 Months")), ..
    )
    

    注意:变量用连字符分隔,因为它们将用于http请求的查询字符串。

    实用程序:

    def get_period_date(period):
        if period == PERIOD_LAST_THREE_MONTHS:
            return timezone.now() - timezone.timedelta(days=90)
        elif period == PERIOD_LAST_SIX_MONTHS:
            return timezone.now() - timezone.timedelta(days=180)
    

    此函数将返回一个日期时间对象来过滤您的查询集。

    表格:

    class DateForm(forms.Form):
        period = forms.ChoiceField(choices=PERIOD_CHOICES, required=False)
    

    查看:

    class PaymentFormView(base.TempleView):
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
            context['payments'] = Payment.objects.filter(date__gte=get_period_date(self.request.GET('period'))
            return context
    

    所以基本上基于表单值我们得到一个日期时间对象并过滤查询集(记住你有一个date 对象)。我使用模板视图而不是表单视图,因为我假设您不想接受发布请求。但是同样你可以使用表单视图并且不允许发布方法,这取决于你(也可以使用基于函数的视图来完成)。还要考虑表单可能为空的可能性,因此 http 请求中的查询字符串可能没有可能导致错误的 period 参数,并按照您的喜好处理这种情况。

    【讨论】: