在 Django 中使用来自 RESTFUL API 的数据的正确方法

Proper way to consume data from RESTFUL API in django

我正在尝试学习 Django,所以虽然我有一个当前的解决方案,但我不确定它是否遵循 Django 中的最佳实践。我想在我的网站上显示来自网络 api 的信息。假设 api url 如下:

http://api.example.com/books?author=edwards&year=2009

Thsis 将 return Edwards 在 2009 年写的书籍列表。按以下格式返回:

{'results':
             [
                {
                   'title':'Book 1',
                   'Author':'Edwards Man',
                   'Year':2009
                },
                {
                   'title':'Book 2',
                   'Author':'Edwards Man',
                   'Year':2009}
           ]
}

目前我正在使用我的视图文件中的 API,如下所示:

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 中,有人可以提供一个如何做到这一点的例子吗?我专门为Whosebug写了上面的例子,所以任何错误纯粹是写在这里的结果。

好吧,有几件事要记住。首先,在这种情况下,您的数据不会经常更改。所以缓存这种响应是一个很好的做法。周围有很多缓存工具,但 redis 是一个流行的选择。或者,您可以选择仅用于缓存的其他 NoSQL 数据库。

其次,展示这些数据的目的是什么?您是否希望您的用户与书籍或作者等互动?如果它只是一个信息,则不需要表格和模型。如果没有,您必须为书籍和作者等提供适当的视图、表格和模型。

考虑到您应该在哪里调用 API 请求,我想说这在很大程度上取决于第二个问题。选项是:

  • views.py 仅显示数据。
  • forms.py 或仍 views.py 不活跃。

我喜欢将这种逻辑放在单独的服务层中的方法 (services.py);您呈现的数据完全不是 Django ORM 意义上的 "model",它不仅仅是简单的 "view" 逻辑。一个干净的封装确保你可以做一些事情,比如控制支持服务的接口(即,让它看起来像 Python API 与带参数的 URL),添加缓存等增强功能,如@sobolevn 所述,隔离测试 API 等

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

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:

import services
class BooksPage(generic.TemplateView):
    def get(self,request):
        books_list = services.get_books('2009', 'edwards')
        return render(request,'books.html',books_list)

另请参阅:

  • Separation of business logic and data access in django

使用序列化程序而不是 .json,因为它在使用 rest-api 时为 return 提供了一些灵活性 formats.As ,提供的序列化程序使用是首选。

同时保持数据处理和获取数据请求在 view.py.The 表单中用于模板而不是业务逻辑。

 <tbody>
                {% if libros %}
                {% for libro in libros %}
                <tr>
                    <td>{{ libro.id }}</td>
                    <td>{{ libro.titulo }}</td>
                    <td>{{ libro.autor }}</td>
                    <td>{{ libro.eiditorial }}</td>
                    <td>{{ libro.descripcion }}</td>
                    <td>{{ libro.cantidad }}</td>
                    <td>{{ libro.Bodega.nombre }}</td>
                    <td>
                        {% if libro.imagen %}
                    <td><img src= "{{ libro.imagen.url }} "align="center" width="50px" ></td>
                    {% else %}
                    <h6>no hay imagen de libros</h6>
                    {% endif %}
                    </td>
                    <td><a class ="btn btn-primary "href="/">Editar</a></td>
                    <td><a class ="btn btn-danger red"href="/">Eliminar</a></td>
                </tr>
                {% endfor %}
                {% else %}
                <h1>no hay registros de libros</h1>
                {% endif%}
            </tbody>

当我已经有了本地应用程序问候语列表时,我可以在 html 中调用它