Django从模型或视图调用REST API? [英] Django calling REST API from models or views?

查看:55
本文介绍了Django从模型或视图调用REST API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须从Django调用外部REST API。外部数据源模式类似于我的Django模型。我应该使远程数据和本地数据保持同步(可能与该问题无关)



问题:


  1. 从哪里调用外部Web服务最合理的地方是:从模型方法还是从视图?

  2. 是否应该将调用远程API的代码放在将由视图随后调用的外部模块中?

  3. 是否可以有条件地选择数据源?意味着根据REST API或本地模型的新鲜程度显示数据?

谢谢



编辑::针对愿意回答这个问题的人们:我从一开始就将问题分解成三个简单的问题,到目前为止,我已经收到了很好的答案,谢谢。

解决方案


  1. 我认为在哪里调用Web服务是一种意见。我想说不要污染您的模型,因为这意味着您可能需要这些模型的实例才能调用这些Web服务。那可能没有任何意义。您的另一选择是在模型上制作 @classmethod ,我认为这不是很干净的设计。



    <如果访问视图本身是触发Web服务调用的原因,则从视图进行调用可能更自然。是吗?您说过需要保持同步,这表明可能需要进行后台处理。那时,如果后台进程发出http请求,您仍然可以使用视图,但这通常不是最佳设计。如果有的话,您可能需要使用自己的REST API,这需要将代码与您的一般网站视图分开。



    我的意见是,这些调用应放在专为远程调用和处理封装的模块和类。这使事情变得灵活(后台作业,信号等),并且也更易于进行单元测试。您可以在视图或其他地方触发调用此代码,但逻辑本身应与视图和模型分开,以使各组件之间更好地分离。



    您应该想象如果没有Django,则该逻辑应该独立存在,然后构建将逻辑与Django连接的其他部分(例如:同步模型) )。换句话说,保持事物原子。


  2. 是的,与上述相同,尤其是灵活性。是不是有任何理由?


  3. 是的,只需创建与接口等效的接口即可。使每个类都映射到接口。如果字段相同并且很懒,则可以在python中将需要的字段作为dict转储到构造函数中(使用* * kwargs )并完成此操作,或使用可以处理的对流重命名密钥。我通常为此构建某种简单的数据映射器类,并在列表理解中处理django或rest模型,但是如果事情如我所说地匹配,则不需要。



    与上述内容相关的另一个选项是,您可以将内容转储到Redis或Memcache之类的缓存中的通用结构中。如果您担心新鲜度,最好自动更新此信息。但是一般来说,您应该有一个单一的权威来源,可以告诉您实际的新鲜事物。在同步情况下,我认为最好选择一个或另一个以使事情可预测和清晰。


一个可能影响设计的最后一件事是,按照定义,保持同步是一个困难的过程。同步往往很容易失败,因此您应该具有某种持久机制,例如任务队列或重试作业系统。在调用远程REST API时,请始终假设由于疯狂的原因(例如网络中断),调用可能会失败。同步时还请记住事务和事务行为。由于这些很重要,因此再次指出以下事实:如果将所有这些逻辑直接放在视图中,则可能会在不使用任何抽象内容的情况下在后台重用它而遇到麻烦。


I have to call external REST APIs from Django. The external data source schemas resemble my Django models. I'm supposed to keep the remote data and local ones in sync (maybe not relevant for the question)

Questions:

  1. What is the most logical place from where to call external web services: from a model method or from a view?
  2. Should I put the code that call the remote API in external modules that will be then called by the views?
  3. Is it possible to conditionally select the data source? Meaning presenting the data from the REST API or the local models depending on their "freshness"?

Thanks

EDIT: for the people willing to close this question: I've broken down the question in three simple questions from the beginning and I've received good answers so far, thanks.

解决方案

  1. I think it is an opinion where to call web services. I would say don't pollute your models because it means you probably need instances of those models to call these web services. That might not make any sense. Your other choice there is to make things @classmethod on the models, which is not very clean design I would argue.

    Calling from the view is probably more natural if accessing the view itself is what triggers the web service call. Is it? You said that you need to keep things in sync, which points to a possible need for background processing. At that point, you can still use views if your background processes issue http requests, but that's often not the best design. If anything, you would probably want your own REST API for this, which necessitates separating the code from your average web site view.

    My opinion is these calls should be placed in modules and classes specifically encapsulated for your remote calls and processing. This makes things flexible (background jobs, signals, etc.) and it is also easier to unit test. You can trigger calling this code in the views or elsewhere, but the logic itself should be separate from both the views and the models to decouple things nicely.

    You should imagine that this logic should exist on its own if there was no Django around it, then build other pieces that connect that logic to Django (ex: syncing the models). In other words, keep things atomic.

  2. Yes, same reasons as above, especially flexibility. Is there any reason not to?

  3. Yes, simply create the equivalent of an interface. Have each class map to the interface. If the fields are the same and you are lazy, in python you can just dump the fields you need as dicts to the constructor (using **kwargs) and be done with it, or rename the keys using some convetion you can process. I usually build some sort of simple data mapper class for this and process the django or rest models in a list comprehension, but no need if things match up as I mentioned.

    Another related option to the above is you can dump things into a common structure in a cache such as Redis or Memcache. It might be wise to atomically update this info if you are concerned with "freshness." But in general you should have a single source of authority that can tell you what is actually fresh. In sync situations, I think it's better to pick one or the other to keep things predictable and clear though.

One last thing that might influence your design is that by definition, keeping things in sync is a difficult process. Syncs tend to be very prone to failure, so you should have some sort of durable mechanism such as a task queue or job system for retries. Always assume when calling a remote REST API that calls can fail for crazy reasons such as network hicups. Also keep in mind transactions and transactional behavior when syncing. Since these are important, it points again to the fact that if you put all this logic in a view directly, you will probably run into trouble reusing it in the background without abstracting things a bit anyway.

这篇关于Django从模型或视图调用REST API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆