2015-06-03 207 views
0

我试图使与我的API相关的某些属性可配置(这些属性与DRF属性无关),它更多是我想用于我自己的应用程序的元数据。为此,我创建了一个应用程序,我称其为API管理的唯一目的,即apimanagerDjango REST框架API管理

我想象的这种实现方式是通过发现DRF中定义的所有API,然后定义一个ModelAdmin类来管理API及其属性。

API发现

方法1:导入定义的URL列表中urls.py并用前缀(如^ API)过滤器 - 我不喜欢这样,因为它依赖于公约,这也导致以循环进口。

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

方法3:穿过每个模块,发现是APIView sublcasses类,然后定义模型,为相关元数据,这样的事情:

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' 

忽略的一流进口和companies实例,这些用于测试目的。

如果我浏览了我的应用程序中的每个模块,但这种方法有效,但感觉有点不好意思,我觉得这样做更简单,更优雅。

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

+2

你有没有想过编写一个小的注册机制,然后从代码中调用类似'apimanager.register(MyApiView)'的东西?在您的应用程序启动后,您可以遍历所有注册的类并实现您的业务逻辑。这不是一个非常聪明的机制,但它读起来很好,并且感觉与Django自己的注册机制(管理员,过滤器,模板标签,...)的机制很接近。 – sthzg

+0

@ sthzg我喜欢这个想法,我会尝试实现某些东西并将其作为答案发布。谢谢。 – abstractpaper

回答

0

在@ 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' 

继承所有DRF来自0123的API将自动构建所有API的列表。这是构建API目录的起点,它可以扩展用于构建更大的API管理包。