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 管理包。
我正在尝试使与我的 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 管理包。