简体   繁体   English

动态编写 django 过滤器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM