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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30259452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:08:15  来源:igfitidea点击:

Proper way to consume data from RESTFUL API in django

pythondjangorestrestful-architecture

提问by user2694306

I'm trying to learn django so while I have a current solution I'm not sure if it follows best practices in django. I would like to display information from a web api on my website. Let's say the api url is as follows:

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

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

Thsis would return a list of books by Edwards written in the year 2009. Returned in the following format:

这将返回爱德华兹在 2009 年写的书的列表。以以下格式返回:

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

Currently I am consuming the API in my views file as follows:

目前我在我的视图文件中使用 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)

Normally, we grab data from the database in the models.py file, but I am unsure if I should be grabbing this API data in models.py or views.py. If it should be in models.py, can someone provide an example of how to do this? I wrote the above example sepecifically for stackoverflow, so any bugs are purely a result of writing it here.

通常,我们从models.py 文件中的数据库中获取数据,但我不确定是否应该在models.py 或views.py 中获取这些API 数据。如果它应该在models.py中,有人可以提供一个如何做到这一点的例子吗?我专门为stackoverflow写了上面的例子,所以任何错误纯粹是在这里写的结果。

采纳答案by bimsapi

I like the approach of putting that kind of logic in a separate service layer (services.py); the data you are rendering is quite not a "model" in the Django ORM sense, and it's more than simple "view" logic. A clean encapsulation ensures you can do things like control the interface to the backing service (i.e., make it look like a Python API vs. URL with parameters), add enhancements such as caching, as @sobolevn mentioned, test the API in isolation, etc.

我喜欢将这种逻辑放在单独的服务层 (services.py) 中的方法;您渲染的数据在 Django ORM 意义上不是“模型”,它不仅仅是简单的“视图”逻辑。干净的封装确保您可以执行诸如控制后备服务的接口(即,使其看起来像 Python API 与带有参数的 URL)、添加增强功能(如@sobolevn 提到的缓存)、单独测试 API、等等。

So I'd suggest a simple services.py, that looks something like this:

所以我建议一个简单的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

Note how the parameters get passed (using a capability of the requestspackage).

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

Then in views.py:

然后在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)

See also:

也可以看看:

回答by sobolevn

Well, there are several things to keep in mind. First of all, in this case your data is not changing so often. So it is a good practice to cache this kind of responces. There are a lot of caching tools around, but redisis a popular option. Alternatevly, you can choose additional NoSQL database just for caching.

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

Secondly, what is the purpose of displaying this data? Are you expecting your users to interact with books or authors, etc? If it is just an information, there is no need in forms and models. If not, you must provide proper views, forms and models for both books and authors, etc.

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

And considering the place where you should call an API request, I would say it dependes heavily on the second question. Choices are:

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

  • views.pyfor just displaying data.
  • forms.pyor still views.pyfor ineractivity.
  • views.py仅用于显示数据。
  • forms.py或者仍然views.py是不活动的。

回答by Prateek099

Use the serializer instead of .json, as it gives flexibility to return in a number of formats.As while using rest-api , the provided serializer use is preferred.

使用序列化程序而不是 .json,因为它可以灵活地以多种格式返回。在使用 rest-api 时,首选使用提供的序列化程序。

Also keep the data handling and get data requests in view.py.The forms are used for templating not as the business logic.

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

回答by Guillermo Andres Montecinos Pa

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

as I can call it in an html when I already have a list of my local application greetings

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