我有多个API类(ModelViewSet
)从一个共同的ViewSet
继承。因此,有不同类型的模型,它们有自己的字段,但都具有相同的特征,这些特征是在共同的viewset
中定义的。
其中一个特性是过滤。它看起来像这样:
class CommonViewSet(viewsets.ModelViewSet):
filter_backends = (DjangoFilterBackend,)
filter_fields = '__all__'
class FirstViewSet(CommonViewSet):
model = FirstModel
class SecondViewSet(CommonViewSet):
model = SecondModel
# etc...
每个模型都有不同的字段集,除了每个模型都有一个公共字段user
。我不希望这个字段以任何方式暴露。
我已经从序列化器中排除了这个字段:
class CommonSerializer(serializers.ModelSerializer):
class Meta:
exclude = ('user',)
class SecondSerializer(CommonSerializer):
class Meta:
model = FirstModel
# etc...
我想要实现的是排除从CommonViewSet
的filter_fields
中取出user
字段。例如:
filter_fields = '__all__' # except 'user'
有标准的方法吗?
我自己找到了解决办法。
为此,我定义了CustomFilterBackend
,它用filter_exclude
扩展了DjangoFilterBackend
的功能:
class CustomFilterBackend(DjangoFilterBackend):
def get_filterset_class(self, view, queryset=None):
filterset = super().get_filterset_class(view, queryset)
filter_exclude = getattr(view, 'filter_exclude', None)
for x in filter_exclude:
filterset.base_filters.pop(x, None)
return filterset
因此,有了这样的过滤器后端,我可以在ModelViewSet
上定义排除字段的附加字段:
class UserCustomViewSet(viewsets.ModelViewSet):
filter_backends = (CustomFilterBackend,)
filter_fields = '__all__'
filter_exclude = ('user',)