使用DjangoFilters有条件地呈现字段

2024-10-01 09:41:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发我的Django SAAS应用程序,我想让用户拥有一些自定义设置,比如禁用或启用某些过滤器。为此,我将django-user-setttingsdjango-filters结合使用,并将简单形式与布尔字段结合使用:

class PropertyFilterSetting(forms.Form):
    filter_by_loans = forms.BooleanField(required=False)
    filter_by_tenants = forms.BooleanField(required=False)

问题是,在尝试应用这些设置时,我总是遇到严重的意大利面代码:

视图.py

class PropertyListView(LoginRequiredMixin, FilterView):
    template_name = 'app/property_list.html'
    context_object_name = 'properties'

    def get_filterset_class(self):
        print(get_user_setting('filter_by_tenants', request=self.request))
        return PropertyFilterWithoutTenant if not get_user_setting('filter_by_tenants', request=self.request)['value'] else PropertyFilter

filter.py

class PropertyFilter(django_filter.FilterSet):
    ...
class PropertyFilterWithoutTenant(PropertyFilter):
    ...

我必须对其余的功能做同样的事情。有没有更好的方法来实现这一点


Tags: djangopyselffalsegetbyrequestrequired
2条回答

我不确定MVT结构将如何准确响应这一点,但我使用REST结构中的自定义泛型类在我想要的任何视图集中添加自定义过滤器字段

class ListAPIViewWithFilter(ListAPIView):
    def get_kwargs_for_filtering(self):

        filtering_kwargs = {}
        if self.my_filter_fields is not []:
            # iterate over the filter fields
            for field in self.my_filter_fields:
                # get the value of a field from request query parameter
                field_value = self.request.query_params.get(field)
                if field_value:
                    filtering_kwargs[field] = field_value
        return filtering_kwargs


    def get_queryset(self):
        queryset = super(ListAPIViewWithFilter, self).get_queryset()
        filtering_kwargs = self.get_kwargs_for_filtering()
        if filtering_kwargs != {}:
            # filter the queryset based on 'filtering_kwargs'
            queryset = queryset.filter(**filtering_kwargs)
            self.pagination_class = None
        else:
            return queryset
        return queryset[:self.filter_results_number_limit]

更改views.py中的原始区域get_queryset函数应该是解决问题的关键(它在django rest中工作)。 尝试检查哪个函数获取数据,然后确定需要的字段

您可以在User模型中创建方法,也可以创建一个新类作为所有方法的存储。每个方法将根据相应用户设置的值为您提供相关的filterset类

比如:

class UserFilterset:
    def __init__(self, request):
        self.request = request
    
    def get_property_filterset(self):
        if not get_user_setting('filter_by_tenants', request=self.request)['value']:
            return PropertyFilterWithoutTenant
        return PropertyFilter
   
    ... # add more such methods for each user setting

现在可以使用此方法获取相关的filterset类

class PropertyListView(LoginRequiredMixin, FilterView):
    template_name = 'app/property_list.html'
    context_object_name = 'properties'

    def get_filterset_class(self):
        return UserFilterset(self.request).get_property_filterset()

因此,即使将来您想要添加更多的逻辑,您也可以只更新相关的方法,这样会更干净、更易于管理

相关问题 更多 >