在 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 中调用它
我正在尝试学习 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 中调用它