Proper way to consume data from RESTFUL API in django
我正在努力学习Django,所以当我有一个当前的解决方案时,我不确定它是否遵循Django的最佳实践。我想在我的网站上显示来自Web API的信息。假设API URL如下所示:
1 | http://api.example.com/books?author=edwards&year=2009 |
THSIS将归还爱德华兹在2009年写的一份书的清单。按以下格式返回:
1 2 3 4 5 6 7 8 9 10 11 12 13 | {'results': [ { 'title':'Book 1', 'Author':'Edwards Man', 'Year':2009 }, { 'title':'Book 2', 'Author':'Edwards Man', 'Year':2009} ] } |
号
目前,我正在使用视图文件中的API,如下所示:
1 2 3 4 5 6 | class BooksPage(generic.TemplateView): def get(self,request): r = requests.get('http://api.example.com/books?author=edwards&year=2009') books = r.json() books_list = {'books':books['results']} return render(request,'books.html',books_list) |
通常,我们从models.py文件中的数据库中获取数据,但我不确定是否应该在models.py或views.py中获取此API数据。如果它应该在models.py中,有人能提供一个如何做到这一点的示例吗?我专门为stackoverflow编写了上面的示例,所以任何bug都是在这里编写的。
我喜欢将这种逻辑放在单独的服务层(service s.py)中的方法;在django-orm意义上,您呈现的数据不是一个"模型",它不仅仅是简单的"视图"逻辑。一个干净的封装确保您可以做一些事情,比如控制到支持服务的接口(即,让它看起来像一个带有参数的python api和url),添加诸如缓存之类的增强功能,如@sobolevn所提到的,隔离地测试api等。
所以我建议使用一个简单的
1 2 3 4 5 6 7 | def get_books(year, author): url = 'http://api.example.com/books' params = {'year': year, 'author': author} r = requests.get(url, params=params) books = r.json() books_list = {'books':books['results']} return books_list |
注意如何传递参数(使用
然后在
1 2 3 4 5 | import services class BooksPage(generic.TemplateView): def get(self,request): books_list = services.get_books('2009', 'edwards') return render(request,'books.html',books_list) |
号
另请参见:
- Django中业务逻辑与数据访问的分离
使用序列化程序而不是.json,因为它提供了以多种格式返回的灵活性。与使用REST API一样,首选提供的序列化程序。
另外,在view.py中保留数据处理和获取数据请求。表单用于模板化,而不是作为业务逻辑。
嗯,有几件事要记住。首先,在这种情况下,您的数据不会经常更改。所以缓存这种响应是一个很好的实践。有很多缓存工具,但Redis是一个流行的选项。或者,您可以选择其他NoSQL数据库进行缓存。
其次,显示这些数据的目的是什么?您是否希望您的用户与书籍或作者等交互?如果只是一个信息,那么表单和模型就不需要了。否则,您必须为书籍和作者等提供适当的视图、表单和模型。
考虑到您应该在哪里调用API请求,我会说它很大程度上依赖于第二个问题。选择包括:
views.py 仅用于显示数据。forms.py 或仍为views.py 表示惰性。