使用 Django 使用 JSON API 数据

Posted

技术标签:

【中文标题】使用 Django 使用 JSON API 数据【英文标题】:Consuming JSON API data with Django 【发布时间】:2021-03-03 05:42:15 【问题描述】:

从 Django 应用程序中,我可以使用来自单独的 Restful API 的数据,但是过滤呢?下面返回所有书籍及其数据。但是,如果我只想按作者、日期等获取书籍怎么办?我想传递作者的姓名参数,例如.../authors-name 或 /?author=name 并仅返回 json 响应中的那些。这可能吗?

views.py

def get_books(request):
    response = requests.get('http://localhost:8090/book/list/').json()
    return render(request, 'books.html', 'response':response)

那么有没有办法像模型对象一样过滤?

【问题讨论】:

我不知道任何在 Python 或 Django 中开箱即用的东西,用于过滤字典列表。您可以使用谓词函数调用filter,该函数对匹配的书返回true,否则返回false。 动态构建谓词并不难,因此您可以编写一个与 Django 的QuerySet/Manager.filter 签名类似的函数,该函数根据关键字参数返回自定义谓词函数。 我决定尝试实现这一点。 另一个想法是尽可能利用您正在使用的 API 的过滤功能。 【参考方案1】:

我能想到三种方法:

    Python 的filter 可以与一些额外的代码一起使用。 QueryableList,这是我见过的最接近 ORM 的列表。 query-filter,采用更实用的方法。

1。内置过滤功能

您可以编写一个函数,该函数返回告诉您列表元素是否匹配的函数,并将生成的函数传递给filter

def filter_pred_factory(**kwargs):

    def predicate(item):
        for key, value in kwargs.items():

            if key not in item or item[key] != value:
                return False

        return True

    return predicate

def get_books(request):
    books_data = requests.get('http://localhost:8090/book/list/').json()
    pred = filter_pred_factory(**request.GET)
    data_filter = filter(pred, books_data)

    # data_filter is cast to a list as a precaution
    # because it is a filter object,
    # which can only be iterated through once before it's exhausted.
    filtered_data = list(data_filter)
    return render(request, 'books.html', 'books': filtered_data)

2。可查询列表

QueryableList 将实现与上述相同的功能,但具有一些额外的功能。除了/books?isbn=1933988673,您还可以使用/books?longDescription__icontains=linux 之类的查询。你可以找到其他功能here

from QueryableList import QueryableListDicts

def get_books(request):
    books_data = requests.get('http://localhost:8090/book/list/').json()
    queryable_books = QueryableListDicts(books_data)
    filtered_data = queryable_books.filter(**request.GET)
    return render(request, 'books.html', 'books':filtered_data)

3。查询过滤器

query-filter 有类似的features,但没有复制 ORM 的面向对象方法。

from query_filter import q_filter, q_items

def get_books(request):
    books_data = requests.get('http://localhost:8090/book/list/').json()
    data_filter = q_filter(books_data, q_items(**request.GET))

    # filtered_data is cast to a list as a precaution
    # because q_filter returns a filter object, 
    # which can only be iterated through once before it's exhausted.
    filtered_data = list(data_filter)
    return render(request, 'books.html', 'books': filtered_data)

值得一提的是我写了query-filter

【讨论】:

感谢您的回复。一个多星期以来,我一直在为此挠头!特定的 API 没有参数,它只是一个列表。我确实考虑过将 api 数据转储到模型中,但后来我认为我让它变得比应该的更复杂。我是自学成才的,所以我需要一些时间来解开你的建议,但它给了我一些方向。一旦我有时间消化这个并做一些测试,我会做出回应。再次感谢您的回复! 我在 GitHub 上找到了一些我认为你想要的东西:github.com/kata198/QueryableList 这里也是 PiPy 链接:pypi.org/project/QueryableList 如果它满足您的需求,我会更新我的答案。反正我的过滤想法还没有完全发展。 嘿@Stubb207,希望你有一个愉快的假期(考虑到世界事件)。我已经更新了我的答案,所以希望现在更清楚了。如果能正确解决您的问题,我将不胜感激。

以上是关于使用 Django 使用 JSON API 数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从 API 调用返回的 JSON 数据使 jquery 自动建议

Django中使用JSON返回数据

Django rest框架拉入外部json数据

如何在 Django 中发出 json rpc 请求?

模型中带有 json 字段的 Django crud api

将 csv 上传到内存中并将 json 发送到 api 的 Django 页面