Package: drf-multiple-settings
DRF ViewSets supporting different settings for actionsTable of ContentsRequirementsInstallationUsageSerializer settingsFilters settingsOrdering settingsget_responsemethodModelViewSetandReadonlyModelViewSetExampleRequirementsDjango REST Framework3.0+InstallationInstall using pip:pipinstalldrf-multiple-settingsUsagedrf-multiple-settingsprovides you with classGenericMultipleSettingsViewSetwhich is a subclass of DRF’sGenericViewSetwith added support of different settings for actions.This ViewSet does not contain any actions, so before you using it you should inherit this class adding mixins with desired actions (e.g.mixins.RetrieveModelMixin,mixins.ListModelMixinto addretrieveandlistactions)Instead of parametrize entire viewset withserializer_class,filterset_class,ordering_fieldsandordering, you should give this parameters to each action. To do so, declare next dictionaries with keys equal action names.Serializer settingsYou must provideserializer_classesdictionary to configure serializers in views, usingGenericMultipleSettingsViewSet. This dictionary is equivalent of GenericAPIViewserializer_classfield and it’s value should contain values of same type.Ifserializer_classesis not provided or does not contain value for processed actionViewConfigurationErrorexception will be raisedFilters settingsIf you wish to use different filtersets for different actions as well (which seems logical), your ViewSet should use filter backend fromdrf_multiple_settings.filter_backendspackage. As of now it contains onlyFilterBackendwhich overridesdjango_filters.rest_framework.DjangoFilterBackendand gives you access tofilterset_classesdictionary. This dictionary is equivalentfilterset_classfield and it’s value should contain values of same type. For more information onfilterset_classanddjango-filtervisitdjango-filter documentation.If you are using filtering backend which does not have implementation indrf_multiple_settings.filter_backendslook at implementation for django-filter and write your own it’s pretty straightforward. Feel free to contact me at github so I can include your implementation of other FilterBackend in package.Ordering settingsIf you wish to use different ordering setting for different actions as well (which also seems logical), your ViewSet
should useMultipleSettingsOrderingFilterwhich gives you access to this dictionaries:Ordering fields dictionary:ordering_fields_setDefault ordering dictionary:ordering_setEach dictionary value should have type of corresponding normal GenericAPIView parameters. See Django REST Framework
documentation if you unsure what it is.get_responsemethodGenericMultipleSettingsViewSetalso providesget_responsemethod for rendering response from action using whatever data you wish using current action’s settings.defget_response(self,data,many):This method gets QuerySet fromdataparameter paginate it if needed, then serialize it using serializer, set to this action and return serialized data asResponse. Parametermanytells serializer if it should serialize more then one element. Example of using this method can be found in Example section.Method designed to be used inside an action-decorated methods. Usage outside actions was not tested.ModelViewSetandReadonlyModelViewSetDRFprovides two default ViewSets:ModelViewSetfor CRUD operations with modelReadOnlyModelViewSetfor read operations with model (listandretrieveactions)To ease it’s usagedrf-multiple-settingsprovidesGenericMultipleSettingsViewSetsubclasses with same functionality:ModelMultipleSettingsViewSetReadOnlyModelMultipleSettingsViewSetExampleFor this example we assume that we have following:Two modelsTitleandIssueThree serializersTitleListSerializer- serializer with main info about titleTitleDetailDerializer- serializer with detail info about titleIssueListSerializerTwo FilterSet classesTitleFilter- title filtersIssueFilter- issue filtersAnd we wish create readonly API with following url structure/title/- list of all titles/title/{id}- detail info of title with id={id}/title/{id}/issues- list of all issues of title with id={id}Additionally we want to allow sorting titles bynameand issues byname,numberandpublish_datewith default ordering onnameascending andpublish_datedescending accordingly and allow user to filter results using corresponding FilterSet classes.We can usedrf-multiple-settingsto implement this API as follows (views.py):fromdjango.shortcutsimportget_object_or_404fromdrf_multiple_settings.filter_backends.django_filtersimportFilterBackendfromdrf_multiple_settings.viewsetsimportReadOnlyModelMultipleSettingsViewSet,MultipleSettingsOrderingFilterfromrest_framework.decoratorsimportaction# ... Models and serializers imports...classTitleViewSet(ComicsDBBaseViewSet):queryset=models.Title.objects.all()filter_backends=(MultipleSettingsOrderingFilter,FilterBackend,)# Serializersserializer_classes={'list':TitleListSerializer,'retrieve':TitleDetailSerializer,'issues':IssueListSerializer}# FilterSetsfilterset_classes={'list':TitleFilter,'issues':IssueFilter}# Ordering Parametersordering_fields_set={'list':("name",),'issues':("name","number","publish_date")}ordering_set={'list':("name",),'issues':("-publish_date",),}@action(detail=True)# detail = True needed so DRF router include {id} in urldefissues(self,request,pk):title=get_object_or_404(models.Title,pk=pk)titles=title.issues.all()titles=self.filter_queryset(titles)returnself.get_response(titles,True)