我必须从Django调用外部REST API。外部数据源模式类似于我的Django模型。我应该保持远程数据和本地数据同步(可能与问题无关)
问题:
由于
编辑:对于愿意结束这个问题的人:我从一开始就在三个简单的问题中分解了这个问题,到目前为止,我已经收到了很好的答案,谢谢
答案 0 :(得分:5)
我认为这是一种调用Web服务的意见。我会说不要污染你的模型,因为这意味着你可能需要这些模型的实例来调用这些Web服务。这可能没有任何意义。你的另一个选择是在模型上制作@classmethod
,我认为这不是很干净的设计。
如果访问视图本身是触发Web服务调用的内容,则从视图调用可能更自然。是吗?你说你需要保持同步,这表明可能需要后台处理。此时,如果后台进程发出http请求,您仍然可以使用视图,但这通常不是最佳设计。如果有的话,您可能需要自己的REST API,这需要将代码与普通网站视图分开。
我的意见是这些调用应放在专门为远程调用和处理封装的模块和类中。这使得事物变得灵活(后台作业,信号等),并且单元测试也更容易。您可以在视图或其他地方触发调用此代码,但逻辑本身应该与视图和模型分开,以便很好地分离事物。
你应该想象,如果周围没有Django,那么这个逻辑应该自己存在,然后构建将该逻辑连接到Django的其他部分(例如:同步模型)。换句话说,保持原子性。
是的,与上述原因相同,尤其是灵活性。有什么理由不去吗?
是的,只需创建一个等效的界面。让每个类映射到接口。如果字段是相同的并且你是懒惰的,在python中你可以将你需要的字段作为dicts转储到构造函数(使用* *kwargs
)并完成它,或者使用一些对话重命名密钥你可以处理。我通常会为此构建一些简单的数据映射器类,并在列表理解中处理django或rest模型,但如果事情与我提到的相符则不需要。
上面的另一个相关选项是你可以将东西转储到Redis或Memcache等缓存中的公共结构中。如果您关注"新鲜度,那么以原子方式更新此信息可能是明智的。"但总的来说,你应该有一个权威来源,可以告诉你什么是新鲜的。在同步的情况下,我认为选择其中一个以保持可预测性和清晰度更好。
可能影响您设计的最后一件事是,根据定义,保持同步是一个困难的过程。同步往往很容易出现故障,因此您应该使用某种持久机制,例如任务队列或作业系统进行重试。始终假设在调用远程REST API时,由于网络慌乱等疯狂原因,调用可能会失败。同步时请记住事务和事务行为。由于这些很重要,它再次指出这样一个事实:如果你把所有这些逻辑直接放在一个视图中,你可能会遇到麻烦在后台重用它而不用抽象一点。
答案 1 :(得分:3)
从哪里调用外部Web服务最合乎逻辑的地方是:从模型方法还是从视图?
理想情况下,您的模型应该只与数据库对话,并且不知道您的业务逻辑发生了什么。
我是否应该将调用远程API的代码放在外部模块中,然后由视图调用?
如果您需要从多个模块访问它们,那么是的,将它们放在模块中是有意义的。这样你就可以有效地重复使用它们。
是否可以有条件地选择数据源?是否意味着根据REST API或本地模型的“新鲜度”来呈现数据?
当然有可能。您可以根据请求实现获取数据的方式。但更有效的方法可能就是避免使用逻辑,只需将本地数据与远程数据同步,并在视图上显示本地数据。