philipn/django-rest-framework-filters

Specify Model Dynamiclly

Closed this issue · 2 comments

Hello,

I want to specify model dynamically, but getting following error

for expr, lookup in model_field.get_lookups().items():
AttributeError: 'NoneType' object has no attribute 'get_lookups'

Here is My Code


class DynamicFilter(filters.FilterSet):
    class Meta:
        model = None
        fields = {'name': '__all__'}

class DynamicAPI():
    def __init__(self, model_name):
        self.model_name = model_name

    def get_params(self):
        response = {"queryset" : self.model_name.objects.all()}
        model_class_name = self.model_name.__name__
        print(model_class_name)
        if model_class_name == "MasterMappingVideoMap":
            instace_serializer = MasterMappingVideoMapSerializer
        else:
            instace_serializer = CommonSerializer
        instace_serializer.Meta.model = self.model_name
        response["serializer_class"] = instace_serializer
        DynamicFilter.Meta.model = self.model_name
        response["filter_class"] = DynamicFilter
        return response

Hi @DanishAbsar. Filters are generated during class creation, so you should just create a new class inside your view code. e.g.,

        response["serializer_class"] = instace_serializer
        DynamicFilter.Meta.model = self.model_name
        class DynamicFilter(FilterSet):
            class Meta:
                model = self.model
                fields = {'name': '__all__'}
        response["filter_class"] = DynamicFilter
        return response

That said, I think this is probably not a great idea, and I would instead recommend creating a filterset class for each of your models, then pass the filterset class as an argument to your view.

Hi @DanishAbsar. Filters are generated during class creation, so you should just create a new class inside your view code. e.g.,

        response["serializer_class"] = instace_serializer
        DynamicFilter.Meta.model = self.model_name
        class DynamicFilter(FilterSet):
            class Meta:
                model = self.model
                fields = {'name': '__all__'}
        response["filter_class"] = DynamicFilter
        return response

That said, I think this is probably not a great idea, and I would instead recommend creating a filterset class for each of your models, then pass the filterset class as an argument to your view.

Thanks for the code @rpkilby