所以我想从django filters.FilterSet创建django-filter module,但我想动态添加其属性。例如,如果我想动态添加SubName
:
class UsersInfoFilter(filters.FilterSet):
Name=NumberFilter(lookup_type='gte')
def __new__(self):
self.SubName=NumberFilter(lookup_type='gte')
self.Meta.fields.append('SubName')
class Meta:
model = UsersInfo
fields = ['UserID', 'LanguageID', 'Name']
问题在于FilterSet是一个元类,它会在类被弄清楚后立即运行,因此在此之前无处可以动态添加项。
我已经尝试将函数作为参数放在filters.FilterSet class UsersInfo(AddObjects(filters.FilterSet))
周围,它确切地返回了传递的内容,但我不能在那时引用UsersInfoFilter
,因为它仍然不是&#39 ; t完成了创作。
我还尝试将UsersInfoFilter
作为自己的基类,然后创建class RealUsersInfoFilter(UsersInfoFilter, filters.FilterSet)
作为我的实际过滤器,但是然后FilterSet会抛出有关缺少属性的警告。
对于python中的类,似乎没有任何类型的构造函数。我假设我必须用元类做一些魔法,但是我已经尝试了我能想到的每一个组合,并且最终处于智慧状态。
答案 0 :(得分:0)
您无法从Meta
方法更改__init__
子类...有两种方法可以解决您的问题......
第一个 - 在所有模型字段上定义“宽”过滤器:
class UsersInfoFilter(filters.FilterSet):
class Meta:
model = UsersInfo
它将为您的所有模型字段创建默认过滤器。
其次,定义动态字段:
class UsersInfoFilter(filters.FilterSet):
name = NumberFilter(lookup_type='gte')
def __init__(self):
super(UsersInfoFilter, self).__init__()
base_filters['subname'] = NumberFilter(name='subname', lookup_type='gte')
class Meta:
model = UsersInfo
fields = ['user_id', 'language_id', 'name']
(我不知道这是否是你真正想要的东西 - 因为尽管“动态”添加字段 - 它应该被声明为静态 - 这里没有逻辑)
P.S。 为什么CamelCase的属性和领域?使用适当的pep-8。
答案 1 :(得分:0)
要动态选择 FilterSet 中的字段,我建议像这样创建一个 FilterSet 工厂:
def filterset_factory(model, fields):
meta = type(str('Meta'), (object,), {'model': model, 'fields': fields})
filterset = type(str('%sFilterSet' % model._meta.object_name),
(FilterSet,), {'Meta': meta})
return filterset
然后像这样使用它:
DynamicFilterClass = filterset_factory(model=MyModel, fields=[...])
dynamic_filter = DynamicFilterClass(request.GET, queryset=instances)