创建从models.Model派生的自定义基础模型。在该模型中添加一个没有对象的空 Resource 类并按照 Tastypie 手册中的说明进行操作:
https://django-tastypie.readthedocs.io/en/latest/non_orm_data_sources.html
从新创建的自定义模型中派生应用程序中的所有模型,您就拥有了。
为了让它工作,你需要一些魔法。我正在使用一个单独的类作为 ORM 和业务层(模型适配器)之间的中间件,但我会说应该可以不用它。
让我苦苦挣扎的是在apiResource的init中传递正确类的方法。
我结束了覆盖init并像这样注册资源:
v1_api.register(BusinessClientContact.apiResource(BusinessClientContact))
不幸的是,没有办法将内容注入到资源的元类中。你可以让它工作,但是当你开始添加资源时,你会发现解释器不会创建类.Meta 和 self._meta 的单独实例,除非你没有对代码进行显式更改。后者使所有修改 _meta 结构的尝试都被动态破坏,因为您在同一个 _meta 实例上工作,而不管您的每个资源都是不同的实例。我使用的解决方法是在我想通过 api 公开的每个模型类中继承 apiResourceBase 类并手动配置 Meta 类。模型类中的代码如下所示:
class apiResource(SystemModelBase.apiResourceBase):
class Meta:
resource_name = 'client_contacts'
#more stuff here
根据您的设计,您可以扩展本地化的 apiResource 以启用自定义视图和过滤器。
资源类本身的示例实现如下所示:
class apiResourceBase(Resource):
def __init__(self,f_modelClass):
self.m_objMetaModel = f_modelClass.create_model_adapter()
super(SystemModelBase.apiResource,self).__init__()
#obj_create
#obj_update
#obj_delete_list
#obj_delete
#rollback
def detail_uri_kwargs(self, bundle_or_obj):
kwargs = {}
if isinstance(bundle_or_obj, Bundle):
kwargs['pk'] = bundle_or_obj.obj.id
else:
kwargs['pk'] = bundle_or_obj.id
return kwargs
def obj_get_list(self, bundle, **kwargs):
return self.get_object_list(bundle.request)
def get_object_list(self,request):
return self.m_objMetaModel.REST_IMPL.get_object_list(request)
def obj_get(self, bundle, **kwargs):
self.m_objMetaModel.load(kwargs['pk'],True)
return self.m_objMetaModel.instance
def dehydrate(self, bundle):
return self.m_objMetaModel.REST_IMPL.dehydrate(bundle)
这里的实际实现(get_object_list 和 dehydrate)超出了范围,但它可能对某人有所帮助,所以我将添加它:
def get_object_list(self,request):
l_clientID = request.GET['client']
l_filterDict = {}
l_filterDict['client_account__id']=l_clientID
return self.query_filter(l_filterDict)
def dehydrate(self,bundle):
l_objInstance = bundle.obj
l_apiDict = {}
l_apiDict['resource_uri'] = bundle.data['resource_uri']
l_apiDict['id'] = l_objInstance.id
l_apiDict['name'] = l_objInstance.user_account.name
l_apiDict['email'] = l_objInstance.user_account.email
l_apiDict['phone'] = l_objInstance.user_account.phone
l_apiDict['additional_contacts'] = l_objInstance.user_account.additional_contacts
l_apiDict['is_active'] = l_objInstance.user_account.user.is_active
bundle.data = l_apiDict
return bundl
这是一个概念验证代码,在生产中,您几乎可以复制 Tastypie 用于加载模型并公开它们的逻辑。