关于python:在django中使用RESTFUL API中的数据的正确方法

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等。

所以我建议使用一个简单的services.py,看起来像这样:

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

注意如何传递参数(使用requests包的功能)。

然后在views.py中:

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表示惰性。