def filter_queryset(self, request: Request, queryset: QuerySet,
                        view: GenericViewSet):
        if (not issubclass(view.get_serializer_class(),
                           FlexFieldsSerializerMixin)
                or request.method != "GET"):
            return queryset

        auto_remove_fields_from_query = getattr(
            view, "auto_remove_fields_from_query", True)
        auto_select_related_on_query = getattr(view,
                                               "auto_select_related_on_query",
                                               True)
        required_query_fields = list(getattr(view, "required_query_fields",
                                             []))

        serializer = view.get_serializer(  # type: FlexFieldsSerializerMixin
            context=view.get_serializer_context())

        serializer.apply_flex_fields()

        model_fields = [
            self._get_field(field.source, queryset.model)
            for field in serializer.fields.values()
            if self._get_field(field.source, queryset.model)
        ]

        nested_model_fields = [
            self._get_field(field.source, queryset.model)
            for field in serializer.fields.values()
            if self._get_field(field.source, queryset.model)
            and field.field_name in serializer.expanded_fields
        ]

        if auto_remove_fields_from_query:
            queryset = queryset.only(*(required_query_fields + [
                model_field.name for model_field in model_fields
                if not model_field.is_relation or model_field.many_to_one
            ]))

        if auto_select_related_on_query and nested_model_fields:
            queryset = queryset.select_related(
                *(model_field.name for model_field in nested_model_fields
                  if model_field.is_relation and model_field.many_to_one))

            queryset = queryset.prefetch_related(
                *(model_field.name for model_field in nested_model_fields
                  if model_field.is_relation and not model_field.many_to_one))

        return queryset
    def _get_not_detail_actions(self,
                                viewset: viewsets.GenericViewSet) -> list:
        not_detail_actions = []

        list_action = getattr(viewset, "list", None)
        if list_action:
            not_detail_actions.append(list_action)

        create_action = getattr(viewset, "create", None)
        if create_action:
            not_detail_actions.append(create_action)

        actions = viewset.get_extra_actions()
        for view_action in actions:
            if not view_action.detail and view_action.__name__ != "permissions":
                not_detail_actions.append(view_action)

        return not_detail_actions
示例#3
0
def paged_response(
    *,
    view: viewsets.GenericViewSet,
    queryset: Optional[QuerySet] = None,
    status_code: Optional[int] = None,
):
    """
    paged_response can be used when there is a need to paginate a custom
    API endpoint.

    Usage:
        class UsersView(ModelViewSet):
            ...

            @action(
                ['get'],
                detail=True,
                serializer_class=PostSerializer,
                filterset_class=PostsFilterSet,
            )
            def posts(self, request: Request, pk: Optional[str] = None):
                queryset = Post.objects.filter(user=self.get_object())
                return paged_response(view=self, queryset=queryset)

    :param view: any instance that statisfies the GenericViewSet interface
    :param queryset: Optional django.db.models.QuerySet.
        Default: get_queryset output
    :param status_code: Optional int
    :return: rest_framework.response.Response
    """
    status_code = status_code or status.HTTP_200_OK
    queryset = queryset or view.get_queryset()
    queryset = view.filter_queryset(queryset)
    page = view.paginate_queryset(queryset)
    if page is not None:
        serializer = view.get_serializer(page, many=True)
        return view.get_paginated_response(serializer.data)

    serializer = view.get_serializer(queryset, many=True)
    return response.Response(serializer.data, status=status_code)
示例#4
0
 def finalize_response(self, request, response, *args, **kwargs):
     request._request.CORS = self.cors_allowed_methods
     return GenericViewSet.finalize_response(self, request, response, *args,
                                             **kwargs)
示例#5
0
 def __init__(self, **kwargs):
     GenericViewSet.__init__(self, **kwargs)
     self.name = self.__class__.__name__.replace('ViewSet', '')
     self.filter_class = eval("{}Filter".format(self.name))
示例#6
0
def test_override_serializer():
    view = GenericViewSet()
    with override_serializer(view, DummySerializer):
        assert view.get_serializer_class() == DummySerializer
示例#7
0
 def __init__(self, **kwargs):
     GenericViewSet.__init__(self, **kwargs)
     self.name = self.__class__.__name__.replace('ViewSet', '')