Ordering items in api root view for DefaultRouter

I use the DefaultRouter provided by DRF because I need the root view of the api. However, the elements in this view do not have any logical order. I looked at the source and found that each entry simply fits into a dictionary (which is not inherently ordered).

class DefaultRouter(SimpleRouter):
    """
    The default router extends the SimpleRouter, but also adds in a default
    API root view, and adds format suffix patterns to the URLs.
    """
    include_root_view = True
    include_format_suffixes = True
    root_view_name = 'api-root'

    def get_api_root_view(self):
        """
        Return a view to use as the API root.
        """
        api_root_dict = {}
        list_name = self.routes[0].name
        for prefix, viewset, basename in self.registry:
            api_root_dict[prefix] = list_name.format(basename=basename)

        class APIRoot(views.APIView):
            _ignore_model_permissions = True

            def get(self, request, format=None):
                ret = {}
                for key, url_name in api_root_dict.items():
                    ret[key] = reverse(url_name, request=request, format=format)
                return Response(ret)

        return APIRoot.as_view()

I would like to order the elements in the root representation of the api in alphabetical order and could easily do this by changing the source code. But I was wondering if you have any solutions for ordering root api elements without changing the source code?

+4
source share
2 answers

, , ​​Denis Cornehi , DefaultRouter, URL- _:

# myapp/routers.py

from rest_framework import routers
from rest_framework import views
from rest_framework.response import Response
from rest_framework.reverse import reverse
import operator
import collections


class OrderedDefaultRouter(routers.DefaultRouter):

    def get_api_root_view(self):
        """
        Return a view to use as the API root but do it with ordered links.
        """
        api_root_dict = {}
        list_name = self.routes[0].name
        for prefix, viewset, basename in self.registry:
            api_root_dict[prefix] = list_name.format(basename=basename)

        class APIRoot(views.APIView):
            _ignore_model_permissions = True

            def get(self, request, format=None):
                ret = {}
                for key, url_name in api_root_dict.items():
                    ret[key] = reverse(url_name, request=request, format=format)
                sorted_ret = collections.OrderedDict(sorted(ret.items(), key=operator.itemgetter(0)))
                return Response(sorted_ret)

        return APIRoot.as_view()
+3

:

  • , , APIRoot ( OrderedDict ). DRF, () .

  • / JSONRenderer, JSON. BrowsableAPIRenderer, . . (, , , DRF).

0

Source: https://habr.com/ru/post/1545269/


All Articles