我可以以编程方式添加大量过滤器吗

Can I add large numbers of filters programmatically

我有一个包含大约 30 列的 table,我想以高度重复的方式将五个过滤器附加到大多数列。所以我希望我可以使用 class 装饰器来根据 this SO answer 定义它们。没有快乐。 TypeError: 'NoneType' object is not callable(在我调用视图的运行时)

无论如何,然后我阅读了有关“适当的”元classing 并尝试

class SettingsMeta(type):
    def __new__(cls, clsname, bases, attrs):

        for name in ('fx_t', 'status'): # just two for now but target ~60 with 5 different lookup_expr
            attr_name = name + '_start'
            attrs[attr_name] =  FD.CharFilter( 
                field_name = name,
                lookup_expr = 'istartswith' ,
                label =  name.replace('_t','').capitalize() + ' starts with',
            )  
        return super(SettingsMeta, cls).__new__(cls, clsname, bases, uppercase_attrs)

class SelectMaskdataFilters( FD.FilterSet, metaclass=SettingsMeta): 
    class Meta:
        model = Maskdata
        fields = {
            'notes':        [ 'icontains',],
        }
    #status_sw = FD.CharFilter( field_name='status', lookup_expr='startswith')
    ...

再次不高兴:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases 在服务器启动时。

SelectMaskDataFilters 本身在视图中按预期工作,如果我只是删除 metaclass=SettingsMeta

我有点不知所措,但我真的不喜欢用一百个左右的过滤器定义来重复自己,所有这些定义几乎都是一样的。那么,除了复制、粘贴和容易出错的小改动之外,有人知道如何在 FilterSet 中定义大量过滤器吗?请注意,大多数过滤器将使用 method= 而不是 lookup_expr=,因此内部 Meta class 中的 fields 属性没有用

您可以在 SelectMaskdataFilters 的本地范围内定义这些:

import django_filters

class SelectMaskdataFilters(django_filters.FilterSet):
    for name in ('fx_t', 'status'):
        label = name.replace('_t','').capitalize()
        <strong>locals()[f'{name}_start']</strong> = django_filters.CharFilter( 
            field_name=name,
            lookup_expr='istartswith' ,
            label=f'{label} starts with'
        )
    
    class Meta:
        model = Maskdata
        fields = {
            'notes': [ 'icontains',],
        }

metaclass 冲突错误是由于您从 (FD.FilterSet) 继承的 class 已经使用了自定义 metaclass。所以,如果你从 type 继承你的,Python 有冲突的元 classes,它不能很好地协同工作:应该调用哪个 metaclass.__new__ 方法?您的元class 或 FD.FilterSet 元class.

中的那个

使其正常工作的方法是让您的元classes 协同工作,并有一个单独的元class 来解决冲突。在这种情况下,您所要做的就是继承 FD.FieldSet 本身的元 class 而不是 type。 (当然,需要调用 superclass 的方法)

您可以使用类型的单参数形式来获取正确的元数据class,您甚至不需要显式导入它。

在您的列表中,只需更改此行:

class SettingsMeta(type):

class SettingsMeta(type(FD.FilterSet)):

一切都应该有效(无需在每个模型的 class 正文中重复自己)