【问题标题】:Django-filters: BaseInFilter with a different separatorDjango-filters:具有不同分隔符的 BaseInFilter
【发布时间】:2020-10-14 05:27:24
【问题描述】:

我希望能够在 django-filters 中以逗号以外的值拆分文本。

我目前正在使用 django-filter 和 BaseInFilter 来允许在模型中搜索多个整数值。此过滤器基于逗号分隔值,我似乎无法覆盖拆分值的函数。我很可能误解了这种分裂发生在哪里。

我已尝试在 BaseCSVWidget 类中重写此方法

def value_from_datadict(self, data, files, name):
    value = super().value_from_datadict(data, files, name)
    if value is not None:
        if value == '':  # empty value should parse as an empty list
            return []
        return value.split(',')
    return None

通过将它放在我的过滤器中并使用不同的分隔符:

class PidnInFilter(BaseInFilter, NumberFilter):
    def value_from_datadict(self, data, files, name):
        value = super().value_from_datadict(data, files, name)

        if value is not None:
            if value == '':  # empty value should parse as an empty list
                return []
            return value.split(' ')
        return None

我也尝试过创建自己的小部件类并在那里覆盖:

from django_filters.widgets import BaseCSVWidget

class MyWidget(BaseCSVWidget):
    def value_from_datadict(self, data, files, name):
        print('value_from_datadict reached')
        print(data)
        value = super().value_from_datadict(data, files, name)
        print(value)

        if value is not None:
            if value == '':  # empty value should parse as an empty list
                return []
            return value.split(' ')
        return None


class PidnInFilter(BaseInFilter, NumberFilter):
    base_widget_class = MyWidget

两者都无法在空格上拆分。理想情况下,我想使用 \n 作为分隔符,或者能够根据上下文选择分隔符。但是,我在发生这种情况的地方遗漏了一些明显的东西......

【问题讨论】:

  • 空格在“CSV”中很少用作分隔符。 CSV 的对应 TSV 按制表符拆分,即 \t。也许您的输入使用制表符?
  • 嗯,我希望能够指定分隔符。该小部件可供用户输入或复制/粘贴值以进行过滤。如果用户在 Excel 中有一堆值要复制/粘贴到小部件中并进行过滤,则分隔符为 \n。但是,在其他情况下,它可能是别的东西
  • 我知道,我的意思是您可能正在使用制表符而不是空格进行测试,所以这就是拆分似乎不起作用的原因。
  • 感谢您的回复,但我已经仔细检查过它不是标签。我尝试了不同的分隔符,手动输入不同的变量。都没有运气

标签: django django-filter


【解决方案1】:

您的问题是类是组合的,而不是继承的:您试图在过滤器上设置小部件,但过滤器定义了一个字段,该字段定义了小部件:

MyFilter
    base_field_class = MyField

    MyField
        base_widget_class = MyWidget

所以在 MyFilter 上设置 base_widget_class 没有任何作用。这应该会让你朝着正确的方向前进(未经测试):

from django_filters.fields import BaseCSVField
from django_filters.widgets import BaseCSVWidget
from django_filters.filters import BaseInFilter, NumberFilter


class PidWidget(BaseCSVWidget):
    separator = " "

    def value_from_datadict(self, data, files, name):
        value = super().value_from_datadict(data, files, name)

        if value is not None:
            if value == "":  # empty value should parse as an empty list
                return []
            return value.split(self.separator)
        return None


class PidField(BaseCSVField):
    base_widget_class = PidWidget


class PidFilter(BaseInFilter, NumberFilter):
    base_field_class = PidField

【讨论】:

    猜你喜欢
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多