django - 在 DefaultRouter 的根 api View 上订购项目

标签 django django-rest-framework

我正在使用 DRF 提供的 DefaultRouter,因为我需要一个根 api View 。但是,该 View 上的项目没有任何逻辑顺序。我查看了源代码,发现每个条目都被放入字典中(本质上没有排序)。

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()

我想按字母顺序对根 api View 上的项目进行排序,并且可以通过修改源轻松实现。但我想知道,你们有没有想过在不修改源代码的情况下订购根 api 项目的解决方案?

最佳答案

根据您的建议和 Denis Cornehi 答案中的第一点,这是 DefaultRouter 的扩展,它按 base_names 对 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()

关于django - 在 DefaultRouter 的根 api View 上订购项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24311893/

相关文章:

python - 将 url 参数传递给序列化器

django - 更改商店的 URL 时,ExtJS 5 应用程序 + Django rest 框架 CORS 错误

python - 如何使用 Django ORM 获取查询集作为连接查询的结果?

python - Django Rest 框架和 JSONField

djangorest框架limit_choices_to属性被忽略?

javascript - 如何在 django 1.6.5 中执行 JavaScript

django - Python opencv等待相机空闲

python - 在 Intellij/Pycharm 中运行 Django 时出错

javascript - {{ oauth_token }} 在源中显示并工作,但不在页面上

python - 为什么 "Models aren' t 已加载”?