Django REST 框架 API 管理

Django REST Framework API Management

我正在尝试使与我的 API 相关的某些属性可配置(这些与 DRF 属性无关),它是我想用于我自己的应用程序的更多元数据。为此,我正在创建一个名为 apimanager 的应用程序,其唯一目的是 API 管理。

我设想的实现方式是发现 DRF 中定义的所有 API,然后定义一个 ModelAdmin class 来管理 APIs 及其属性。

API发现

方法 1:在 urls.py 中导入定义的 url 列表并使用前缀过滤它(例如 ^api)——我不喜欢这个,因为它依赖于约定,而且它也导致循环导入。

方法 2:在 module/api/view/ 文件夹中定义我的 APIs 并找到每个 python 文件中定义的 classes - 我也不喜欢这样.

方法 3:遍历每个模块并找到作为 APIView 子类的 classes,然后为相关元数据定义一个模型,如下所示:

class API(models.Model):
    from modules.companies.api.view import companies
    _apis = (
        (x,x) for x in (lambda m: [
            m.__dict__[c] for c in m.__dict__ if (
                isinstance(m.__dict__[c], type) and m.__dict__[c].__module__ == m.__name__
            )
        ])(companies) if issubclass(x, APIView)
    )

    api = models.CharField(max_length=256, choices=_apis)

    class Meta:
        verbose_name = 'API'
        verbose_name_plural = 'APIs'

忽略 in-class 导入和 companies 实例,这些用于测试目的。

如果我遍历我的应用程序中的每个模块,这种方法会奏效,但感觉有点老套,我觉得有一种更简单、更优雅的方法可以做到这一点。

你会如何解决这个问题?您将如何设计 API 管理应用程序?

根据@sthzg 的评论,我做了一个基于注册的方法,效果很好。

registration.py:

def register_api(cls):
    try:
        # check for membership
        api = API.objects.get(
            module=cls.__class__.__module__,
            name=cls.__class__.__name__,
        )

        # update api
    except API.DoesNotExist:
        # register api
        api = API(
            module=cls.__class__.__module__,
            name=cls.__class__.__name__,
        )
        api.save()

models.py:

class API(models.Model):
    module = models.CharField(max_length=256)
    name = models.CharField(max_length=128)

    def get_class(self):
        return locate('%s.%s' % (self.module, self.name))

    class Meta:
        verbose_name = 'API'
        verbose_name_plural = 'APIs'
        unique_together = ('module', 'name')

    def __unicode__(self):
        return '%s' % self.name

对于我想注册的 API:

class APIManagerMember(object):
    def __init__(self):
        super(APIManagerMember, self).__init__()
        register_api(self)


class CompanyViewSet(APIManagerMember, viewsets.ModelViewSet):
    queryset = Company.objects.all()
    serializer_class = CompanySerializer
    lookup_url_kwarg = 'company_id'

APIManagerMember 继承所有 DRF API 将自动构建一个包含所有 API 的列表。这是构建 API 目录的起点,可以扩展它以构建更大的 api 管理包。