Repository: wagtail/wagtail
File: wagtail/api/v2/views.py (Python)

Code before:
        queryset = self.get_queryset()

        try:
            obj = self.find_object(queryset, request)

            if obj is None:
                raise self.model.DoesNotExist

        except self.model.DoesNotExist:
            raise Http404("not found")

        # Generate redirect
        url = get_object_detail_url(
            self.request.wagtailapi_router, request, self.model, obj.pk
        )

        if url is None:
            # Shouldn't happen unless this endpoint isn't actually installed in the router
            raise Exception(
                "Cannot generate URL to detail view. Is '{}' installed in the API router?".format(
                    self.__class__.__name__
                )
            )

        if "fields" in request.GET:
            url = url + "?fields=" + request.GET["fields"]

        return redirect(url)

    def find_object(self, queryset, request):
        """
        Override this to implement more find methods.
        """
        if "id" in request.GET:
            return queryset.get(id=request.GET["id"])

    def handle_exception(self, exc):
        if isinstance(exc, Http404):
            data = {"message": str(exc)}
            return Response(data, status=status.HTTP_404_NOT_FOUND)
        elif isinstance(exc, BadRequestError):
            data = {"message": str(exc)}
            return Response(data, status=status.HTTP_400_BAD_REQUEST)
        return super().handle_exception(exc)

    @classmethod
    def _convert_api_fields(cls, fields):
        return [
            field if isinstance(field, APIField) else APIField(field)
            for field in fields
        ]

Review comment (suggestion):
I'm not sure which one is better:
1. retain all query parameters in `request.GET` except ones used for finding the object i.e. `html_path` in this case, or
2. only retain `fields` explicitly and disregard all other parameters

In practice it doesn't really matter because I believe `fields` is the only query parameter supported by the detail view at the moment. If we add more in the future, then we'll need to make sure the same is applied here.

Although looking at the code, it seems this view is in the generic `BaseAPIViewSet`, while `html_path` is specific to `PageAPIViewSet`. This means if we want to do the (1) approach, we need to have something like `find_query_parameters = []` in the `BaseAPIViewSet` that is then overridden to be `["html_path"]` in the `PageAPIViewSet`. Then, do a `querydict.pop(q, None)` for each element in the list. 

The issue in #6577 seems to lean towards (1), and I tend to agree. I've got it working locally so I'll push the changes and merge. Thanks!

Code after:
    def find_view(self, request):
        queryset = self.get_queryset()

        try:
            obj = self.find_object(queryset, request)

            if obj is None:
                raise self.model.DoesNotExist

        except self.model.DoesNotExist:
            raise Http404("not found")

        # Generate redirect
        url = get_object_detail_url(
            self.request.wagtailapi_router, request, self.model, obj.pk
        )

        if url is None:
            # Shouldn't happen unless this endpoint isn't actually installed in the router
            raise Exception(
                "Cannot generate URL to detail view. Is '{}' installed in the API router?".format(
                    self.__class__.__name__
                )
            )

        # Retain all query parameters except ones only used to find the object
        query = request.GET.copy()
        for param in self.find_query_parameters:
            query.pop(param, None)

        return redirect(f"{url}?{query.urlencode()}")

    def find_object(self, queryset, request):
        """
        Override this to implement more find methods.
        """
        if "id" in request.GET:
            return queryset.get(id=request.GET["id"])

    def handle_exception(self, exc):
        if isinstance(exc, Http404):
            data = {"message": str(exc)}
            return Response(data, status=status.HTTP_404_NOT_FOUND)
        elif isinstance(exc, BadRequestError):
            data = {"message": str(exc)}
            return Response(data, status=status.HTTP_400_BAD_REQUEST)
        return super().handle_exception(exc)

    @classmethod
    def _convert_api_fields(cls, fields):
        return [