我正在尝试学习django所以当我有一个当前的解决方案时,我不确定它是否遵循django中的最佳实践。我想在我的网站上显示来自网络API的信息。假设api url如下:
http://api.example.com/books?author=edwards&year=2009
Thsis将返回爱德华兹在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中,有人可以举例说明如何做到这一点吗?我特意为stackoverflow编写了上面的例子,所以任何bug都纯粹是在这里写的结果。
答案 0 :(得分:95)
我喜欢将这种逻辑放在单独的服务层(services.py)中的方法;你渲染的数据不是"模型"在Django ORM意义上,它不仅仅是简单的" 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)
另见:
答案 1 :(得分:3)
使用序列化程序而不是.json,因为它可以灵活地以多种格式返回。在使用rest-api时,首选使用提供的序列化程序。
同时保持数据处理并在view.py中获取数据请求。表单用于模板化而不是业务逻辑。
答案 2 :(得分:1)
嗯,有几点要记住。首先,在这种情况下,您的数据不会经常变化。因此,缓存此类响应是一种很好的做法。有很多缓存工具,但redis是一个很受欢迎的选择。另外,您可以选择其他NoSQL数据库进行缓存。
其次,显示此数据的目的是什么?您是否希望您的用户与书籍或作者等进行互动?如果它只是一个信息,则不需要表格和模型。如果没有,您必须为书籍和作者等提供适当的观点,表格和模型。
考虑到你应该调用API请求的地方,我会说它在很大程度上依赖于第二个问题。选择是:
views.py
仅显示数据。forms.py
或仍然views.py
表示不足。答案 3 :(得分:-1)
<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来调用它