如何使Django模板从视图中呈现一组结果并在不刷新页面的情况下继续调用视图以获得更多结果

How to make Django template render a set of results from views and keep calling view for more results without refreshing page

我正在制作一个 Twitter 应用程序,它根据搜索查询从 Twitter REST API 中获取推文。现在根据这些结果,我只想在前端显示那些转推次数超过 2 次的推文。对于我的查询,每 100 条推文中只有几条满足此条件的推文。因此,要显示 100 条转发次数超过 2 次的推文,我必须处理 5-10k 条推文。但是一次 API 调用最多可以获取 100 条推文。

现在,如果我在我的 views.py 中获取 5-10k 条推文,处理它们,提取我需要的推文,然后将其作为上下文传递给 django 模板 -(或者我只是传递 api 结果是模板,只显示符合条件的推文),- 那么它显然不会工作,因为用户不能等待网站加载,直到所有推文都被处理。大多数情况下会发生超时。

那么有什么方法可以让我:

  1. 在视图中获取调用中的前 100 条推文。
  2. 在模板(前端)上渲染满足条件的推文
  3. 在后台保持 views.py 运行 api 调用,并在不刷新页面的情况下继续呈现满足模板上当前结果集以下条件的推文。

我使用的 Twitter 库是 Tweepy。

views.py:

import tweepy
def index(request):
    try:
        query = 'qwerty'
        ###
        # Twitter Api authorization code here
        ###
        api = tweepy.API(auth)
        tweets = tweepy.Cursor(api.search, q=query, count=100).items(100)
        context = {'tweets': results,
                   'query':query,}
    except (KeyError):
        raise
    else:
        return render(request, 'tweets/index.html', context)
def index(request):

模板:

{% for tweet in tweets %}
    {% if tweet.retweet_count >=2 %}
        //Display the tweets
        Tweet: {{ tweet.text }}
    {% endif %}
{% endfor %}

或者有没有一种方法可以动态地从 django 模板本身进行调用?但是,这会呈现结果并加载到目前为止获取的任何内容并在页面加载后进行剩余调用,还是只是等待在页面完全加载之前进行所有调用?

你能通过AJAX从模板中调用这个视图吗?如果可以将此与 AJAX 一起使用,则可以使用分页。只需要从 ajax 请求中获取两个参数(开始,结束)。在您的模板中,您可以像下面这样调用 AJAX 请求:

$(document).ready(function(){
    $.ajax({
         type: "POST",
         url: '{% url "ajax-filter-tweets" %}',
         data: {'start':100, 'end':200},
         dataType: "json",
         success: function(data) {
         //append new tweets via js code here
         // at the end send another ajax if more tweets in queue
    },
    error: function(){
        //your error handling here
        }
    });
});

您可以将 $.ajax() 函数发送到此视图的 url,并且在它的成功部分,您可以使用开始和结束索引调用新的 ajax 函数。您需要自定义过滤器视图或为 ajax 请求生成一个新视图(从开始索引到结束索引结果过滤)。您可以通过 javascript 在 ajax 请求之间设置超时。您也可以使用 "pagination" 关键字搜索此类问题。 Pagination Example 可能会帮助您获取示例代码。

Deniz KAPLAN 提供的 不适用于您的情况,因为您使用的是 Twitter API。 Twitter 不遵循分页过程。当您要迭代的数据是固定的并且不会不断更新时,分页很有用。

查看此 link 以了解 Twitter 的时间轴是如何工作的。

无论如何,您需要做的就是利用 max_id 变量。 max_id 基本上是您获取的最后一条推文的 ID。

因此,当您进行 AJAX 调用时,您应该发送的数据是 max_id 值。

...
data: {'max_id': 3, 'query': 'qwerty'} //Append additional data if required.
...

现在,确保您有另一个视图函数来处理您的 AJAX 请求。该函数看起来有点像这样。

from django.utils import simplejson
from django.http import HttpResponse

def ajax_tweets(request):
    if request.method == 'GET':
        max_id = int(request.GET['max_id'])
        query = request.GET['query']

        ###
        # Perform API auth requirements
        ###

        tweets = tweepy.Cursor(api.search, q=query, max_id=max_id, count=100).items(100)
        json = simplejson.dumps(tweets)

        return HttpResponse(json, mimetype="application/x-javascript")

现在,在 AJAX 调用的 success 函数中,浏览器将获取发送的 JSON 对象。然后您可以进行所需的更改。

...
success: function(data) {
     data = JSON.parse(data);
     //Perform DOM manipulations to append your tweets to your page
},
...

您可以在 AJAX 函数周围添加一个循环,其条件取决于您希望在页面上显示的推文数量。

我希望这个解释对你有帮助。