【问题标题】:Dynamically write django filters动态编写 django 过滤器
【发布时间】:2020-02-06 14:13:20
【问题描述】:

我有几个模型的 Django 过滤器。但它们都有相同的过滤方式如何使其干燥。

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__'

两个类的代码相同。我试图在 utils 中移动代码部分,如 generic_filter 函数并将函数导入过滤器文件,但过滤器不起作用。

【问题讨论】:

    标签: python django python-3.x django-filter django-filters


    【解决方案1】:

    您应该能够编写返回类的工厂函数。可以使用type 的三参数形式来定义一个类。我也不完全理解field_name__contains 的用法。贴出的代码明显有缩进错误。

    这是我的想法,完全没有任何调试

    上次我写了这样的东西,当我开始工作时,我后悔打扰了。但是,这可能是一次学习经历。如果您将这些东西一打一打,那可能值得您花时间。否则,这可能是另一种 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
    

    用法

    TestFilter = FilterFactory(  Test, 'TestFilter')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2011-08-11
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多