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

时间:2022-09-15 21:54:35

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 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将会在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 *, so any bugs are purely a result of writing it here.

通常,我们从模型中获取数据库中的数据。py文件,但是我不确定是否应该在模型中获取这个API数据。py或views.py。如果是在模型中。py,有人能举个例子吗?我为*写了上面的例子,所以所有的bug都是写在这里的结果。

3 个解决方案

#1


74  

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:

所以我想建议一个简单的服务。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).

注意参数是如何通过的(使用请求包的功能)。

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:

参见:

#2


3  

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中获取数据请求。表单用于模板,而不是作为业务逻辑。

#3


1  

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. 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.py for just displaying data.
  • 的观点。py用于显示数据。
  • forms.py or still views.py for ineractivity.
  • 形式。py或仍将。py ineractivity。

#1


74  

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:

所以我想建议一个简单的服务。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).

注意参数是如何通过的(使用请求包的功能)。

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:

参见:

#2


3  

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中获取数据请求。表单用于模板,而不是作为业务逻辑。

#3


1  

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. 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.py for just displaying data.
  • 的观点。py用于显示数据。
  • forms.py or still views.py for ineractivity.
  • 形式。py或仍将。py ineractivity。