[英]Dynamically write django filters
I have a Django filters for couple of models.我有几个模型的 Django 过滤器。 but they both have same filtering how to make it DRY.
但他们都有相同的过滤如何使它干燥。
class TestFilter(django_filters.FilterSet):
field_list = Test._meta.get_fields()
for field in field_list:
field_name = (field.__str__().split('.'))[-1]
if type(field) is model.CharField:
field_name__contains = field_name + '__contains'
vars()[field_name] = django_filters.CharField(field_name=field_name, lookup_expr='iexact')
vars()[field_name] = django_filters.CharField(field_name=field_name, lookup_expr='icontains')
class Meta:
model = Test
fields = '__all__'
class Test2Filter(django_filters.FilterSet):
field_list = Test2._meta.get_fields()
for field in field_list:
field_name = (field.__str__().split('.'))[-1]
if type(field) is model.CharField:
field_name__contains = field_name + '__contains'
vars()[field_name] = django_filters.CharField(field_name=field_name, lookup_expr='iexact')
vars()[field_name] = django_filters.CharField(field_name=field_name, lookup_expr='icontains')
class Meta:
model = Test2
fields = '__all__'
both classes have same code.两个类都有相同的代码。 I tried to move code part in utils like generic_filter function and import the function to filters file but filters are not working.
我尝试在 utils 中移动代码部分,如 generic_filter 函数并将该函数导入过滤器文件,但过滤器不起作用。
You should be able to write a factory function that returns a class.您应该能够编写一个返回类的工厂函数。 A class can be defined by use of the 3-argument form of
type
.可以使用
type
的 3 参数形式定义type
。 I didn't completely understand the use of field_name__contains
either.我也不完全理解
field_name__contains
的用法。 The posted code clearly has an indentation bug.发布的代码显然有一个缩进错误。
This is off the top of my head and completely without debugging of any sort这是我的头顶,完全没有任何调试
Last time I wrote something like this, by the time I got it working I regretted having bothered.上次我写了这样的东西,当我开始工作时,我后悔打扰了。 However, it may have been a learning experience.
然而,这可能是一次学习经历。 If you are cranking these things out by the dozen, it may be worth your while.
如果您将这些东西打成一打,那可能值得您花时间。 Otherwise this may be a case for the other sort of DRY (DO Repeat Yourself)!
否则,这可能是另一种 DRY(请重复自己)的情况!
def FilterFactory( model_class, class_name):
class_vars = {}
field_list = model_class._meta.get_fields()
for field in field_list:
field_name = (field.__str__().split('.'))[-1]
if type(field) is model.CharField:
field_name__contains = field_name + '__contains'
class_vars[field_name] = \
django_filters.CharField(field_name=field_name, lookup_expr='iexact')
class_vars[field_name+'_contains'] = \
django_filters.CharField(field_name=field_name__contains, lookup_expr='icontains')
class_vars['Meta'] = type( 'Meta', (object, ), {
"model": model_class,
"fields": "__all__"
}
)
klass = type( class_name, (django_filters.FilterSet, ), class_vars )
return klass
Usage用法
TestFilter = FilterFactory( Test, 'TestFilter')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.