Flask — Как я могу разбивать данные на страницы, поступающие из API? (Нет базы данных)

#python #api #flask

Вопрос:

Итак, я хочу иметь возможность разбивать на страницы данные, поступающие из API, но я не уверен, как это сделать. Я посмотрел на разбиение на страницы с помощью Flask, и почти все используют SQLAlchemy и базу данных для разбиения на страницы, поэтому я сейчас немного застрял. Я перепробовал все, но мне не повезло, поэтому я надеюсь, что вы, ребята, сможете помочь мне в этом вопросе. Большое спасибо.

Это код, который возвращает мне данные из API:

 from flask import Flask
from flask import render_template
import requests
from flask import request
app = Flask(__name__)

api = '12589634-45tg33ww8633f1cdfrre3345'
url = 'https://pixabay.com/api/'

@app.route("/", methods=['POST', 'GET'])
def homePage():

    per_page = 18
    page = request.args.get('page', 0, type=int)
    query = request.args.get('s', 'cats')
    
    payload = {'key': api, 'q': query, 'per_page': per_page, 'page': page}
    response = requests.get(url, params=payload)
    data = response.json()
    results = data.get('hits')
    images = results

    return render_template('home_page.html', images=images)

Here is my template:

<pre>
{% extends 'base.html' %}

{% block content %}
    <div class="columns is-multiline is-mobile">
        {% for image in images %}
        <div class="column is-full-mobile is-half-tablet is-one-third-desktop">
            <div class="card">
                <div class="card-image">
                    <figure class="image is-4by3">
                        <img src="{{image.webformatURL}}" alt="{{image.tags}}">
                    </figure>
                </div>
                <div class="card-content">
                    <div class="media">
                        <div class="media-left">
                            <figure class="image is-48x48">
                                {% if image.userImageURL %}
                                <img src="{{image.userImageURL}}" alt="{{image.user}}">
                                {% else %}
                                <img src="{{url_for('static', filename='images/avatar/avatar.png')}}" alt="no user image">
                                {% endif %}
                            </figure>
                        </div>
                        <div class="media-content">
                            <p class="title is-5">Uploaded by</p>
                            <p class="subtitle is-6">@{{image.user}}</p>
                        </div>
                    </div>
                    <div class="content">
                        <p class="title is-6">Likes: {{image.likes}}</p>
                        <p class="title is-6">Type: {{image.type}}</p>
                        <p class="title is-6">Views: {{image.views}}</p>
                        <a href="{{image.largeImageURL}}" class="button is-dark is-fullwidth" target="_blank"
                            rel="noopener nofollow">View
                            full</a>
                    </div>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
    <nav class="pagination" role="navigation" aria-label="pagination">
        <a class="pagination-previous" title="This is the first page" disabled>Previous</a>
        <a class="pagination-next">Next page</a>
        <ul class="pagination-list">
            <li>
                <a class="pagination-link is-current" aria-label="Page 1" aria-current="page">1</a>
            </li>
            <li>
                <a class="pagination-link" aria-label="Goto page 2">2</a>
            </li>
            <li>
                <a class="pagination-link" aria-label="Goto page 3">3</a>
            </li>
        </ul>
    </nav>
{% endblock content %}
</pre>
    
 

Комментарии:

1. Один из вариантов состоит в том, чтобы иметь количество изображений на странице по умолчанию, а затем возвращать изображения в виде списка списков длиной, равной количеству изображений на странице. Затем у вас может быть счетчик для навигации по результатам.

Ответ №1:

Я думаю, вы можете сделать пользовательский пагинатор. Простой пример к этому.

 [...]
ques =   images # the images variable you are passing.

page_num = request.args.get("page_num")
no_of_ques = request.args.get("no_of_ques")
# some error handling
try:
    no_of_ques = int(no_of_ques)
except:
    no_of_ques = 10
    
if page_num == None:
    page_num = 0

try: 
    page_num = int(page_num) 
except:
    abort(404) 
# logic to get the last page
last = math.ceil(len(ques)/no_of_ques) - 1
# logic to get images on a page
ques1 = ques[page_num*no_of_ques:(page_num 1)*no_of_ques] # paginatted
# making the links for a  tagsg
if last == 0:
    next = "#"
    prev = "#"
elif page_num == 0:
    next = f"/?page_num={page_num 1}"
    prev = "#"
elif page_num == last:
    next = "#"
    prev = f"/?page_num={page_num-1}"
else:
    next = f"/?page_num={page_num 1}"
    prev = f"/?page_num={page_num-1}"

if (page_num > last  or not str(page_num).isnumeric(): 
    abort(404) 
return render_template("html_file.html",images=ques1,next=next,prev=prev)

# ques1 has the number of images on  a page.
 

в html сделайте два тега

 <a   class="btn btn-primary" src="{{prev}}" >amp;larr; prev</a>
<a  class="btn btn-primary" src={{next}} >Next →</a>
 

Возможно, это не лучшее решение, но оно сделает свою работу.