简体   繁体   English

在django中使用RESTFUL API中的数据的正确方法

[英]Proper way to consume data from RESTFUL API in django

I'm trying to learn django so while I have a current solution I'm not sure if it follows best practices in django. 我正在尝试学习django所以当我有一个当前的解决方案时,我不确定它是否遵循django中的最佳实践。 I would like to display information from a web api on my website. 我想在我的网站上显示来自网络API的信息。 Let's say the api url is as follows: 假设api url如下:

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: Thsis将返回Edwards于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. 通常,我们从models.py文件中的数据库中获取数据,但我不确定是否应该在models.py或views.py中获取此API数据。 If it should be in models.py, can someone provide an example of how to do this? 如果它应该在models.py中,有人可以举例说明如何做到这一点吗? I wrote the above example sepecifically for stackoverflow, so any bugs are purely a result of writing it here. 我特意为stackoverflow编写了上面的例子,所以任何bug都纯粹是在这里编写它的结果。

I like the approach of putting that kind of logic in a separate service layer (services.py); 我喜欢将这种逻辑放在一个单独的服务层(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. 你渲染的数据在Django ORM意义上并不是一个“模型”,它不仅仅是简单的“视图”逻辑。 A clean encapsulation ensures you can do things like control the interface to the backing service (ie, 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. 干净的封装确保您可以执行诸如控制支持服务的接口(例如,使其看起来像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 requests package). 注意参数是如何传递的(使用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: 也可以看看:

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中保持数据处理和获取数据请求。表单用于模板化而不是业务逻辑。

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 redis is a popular option. 有很多缓存工具,但redis是一个受欢迎的选择。 Alternatevly, you can choose additional NoSQL database just for caching. 另外,您可以选择其他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. 考虑到你应该调用API请求的地方,我会说它严重依赖于第二个问题。 Choices are: 选择是:

  • views.py for just displaying data. views.py只显示数据。
  • forms.py or still views.py for ineractivity. forms.py或still views.py表示不活泼。
 <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中调用它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM