自定义 DateRangeFilter 未按预期执行

时间:2021-06-21 15:59:04

标签: django-filter

我正在尝试自定义 django-filterDateRangeFilter。我已经有一个可用的过滤器,可以过滤一系列预设选项,例如过去或即将到来的 30 天。

它还具有用于过滤特定年份的工作选项,尽管是硬编码的,例如:

filters = {

    ...

    ),
    "past_years_minus_1": lambda qs, name: qs.filter(
        **{
            "%s__year" % name: now().year - 1,
        }
    ),
    "past_years_minus_2": lambda qs, name: qs.filter(
        **{
            "%s__year" % name: now().year - 2,
        }
    ),

我希望添加的是能够动态创建一系列单年选择,特定于正在过滤的模型/字段的现有实例。因此,如果从 2019 年开始有模型 A 的实例,那么 20192020 会有选项 - 但不会更早,但是对于模型 B 会有选项如果适用,2014 起。

我创建了一个 __init__ 覆盖来确定所需的年份并适当地扩展选项和过滤器(在本例中为 2017、2018、2019 和 2020)。

def __init__(self, *args, **kwargs):
    """ Create filter options for every year of the span of years of the corresponding model instances """
    """ Pass in model as class, field as str """
    model = kwargs.pop("model", None)
    field = kwargs.pop("field", None)
    super(OrderDateRangeFilter, self).__init__(*args, **kwargs)

    if model and field:
        earliest_obj = model.objects.earliest()
        earliest_year = getattr(earliest_obj, field).year

        current_year = dt.date.today().year

        range_of_years = [
            earliest_year + i
            for i in range(current_year - earliest_year)
            if earliest_year + i <= current_year
        ]
        range_of_years.reverse()

        for year in range_of_years:

            self.choices.append((f"{year}", _(f"{year}")))

            self.filters[f"{year}"] = lambda qs, name: qs.filter(
                **{
                    "%s__year" % name: year,
                }
            )

添加的选项按预期呈现(检查 select 小部件):

  <option value="2020">2020</option>
  <option value="2019" selected>2019</option>
  <option value="2018">2018</option>
  <option value="2017">2017</option>

url 查询字符串反映了所需的选择:

...&date_delivery_scheduled=2019&client=...

但是底层过滤器并没有像我预期的那样执行:返回的结果总是只针对第一年(2017 年),无论选择什么年份,​​并且通过 django-debug-toolbar 报告的底层 SQL 显示 {{ 1}} 最终构建了一个只返回第一年的查询:

django-filter

正如我所说,如果我对过滤器进行硬编码(例如明确针对“2018”等,或者作为过滤器定义中 SELECT ••• FROM "sales_order" WHERE "sales_order"."date_delivery_scheduled" BETWEEN '2017-01-01'::date AND '2017-12-31'::date 的一系列偏移量,则没有问题。它只是添加来自 now() 的过滤器,语法相同,但存在问题。

非常欢迎任何想法

0 个答案:

没有答案