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

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

Thsis将归还一份爱德华兹2009年写的书的 list .以以下格式返回:

{'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)

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

推荐答案

我喜欢将这种逻辑放在单独的服务层(services.py)中的方法;呈现的数据并不是Django ORM意义上的"模型",它不仅仅是简单的"视图"逻辑.一个干净的封装可以确保你可以做一些事情,比如控制支持服务的接口(例如,让它看起来像一个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)

另见:

Django相关问答推荐

如何在Django模板中为无效词典查找打开异常?

通过get_form_kwargs将请求传递给Django表单未能使表单访问self.request.user.

反向 url django 管理员

Django Rest Framework 认证类覆盖 request.user

"" 需要有字段 "id" 的值才能使用这种多对多关系

如何从不是 django 元素文件夹的文件夹中运行 gunicorn

Django - 强制执行 ManyToManyField 唯一项

URL命名空间的一个真实例子

Django:显示在每个页面上加载页面所花费的时间

django 模板中对象的模型名称

单击弹出框会滚动回页面顶部 [Bootstrap 和 Django]

Django ORM 能否以可靠的与后端无关的方式存储无符号 64 位整数(又名 ulong64 或 uint64)?

在 Django 中使用邮箱地址或用户名登录用户

获取 django 应用的绝对路径

如何在 Django 中使用动态外键?

在 Django 开发服务器中关闭静态文件的缓存

Django Rest 框架 ImageField

AttributeError:ManyRelatedManager对象没有add属性?

ImportError:没有名为 django_filters 的模块

获取'str'对象在Django中没有属性'get'