如何在Django应用中实现Shopify API分页功能?
Django + Shopify API 分页实现方案
问题背景
我正在Django应用中尝试通过Shopify API实现订单列表的分页功能,已知Shopify API支持返回上一页、下一页的链接,但不清楚如何在Django项目中具体落地。以下是当前的view代码和模板代码:
当前View代码
import shopify from shopify_app.decorators import shop_login_required @shop_login_required def index(request): orders = shopify.Order.find(status='any') return render(request, 'home/index.html', {'orders': orders})
当前index.html模板
{% extends "base.html" %} {% load template_tags %} {% block content %} <div id="orders"> <div style="display: flex;"> <h2 style="width: 50%;">Your recent orders</h2> </div> {% if orders %} <div class="order-list"> <p id="page-toggle"> <a href="#"> <span id="prev-page">< <b>PREV PAGE</b> </span> </a> <a href=""> <span id="next-page"> <b>NEXT PAGE</b>> </span> </a> </p> {% for order in orders %} <div class="order box"> <div class="wrapper"> <a style='width: 25%; color: black;' href="https://{{ current_shop.domain }}/admin/orders/{{ order.id }}" target="_blank">{{ order.name }}</a> <span style='width: 25%;'>{{ order.created_at | convert_str_date }}</span> <span style='width: 25%;'>{{ order.total_price }} {{ order.currency }}</span> <span style='width: 25%;'>From: {{ order.billing_address.name }}</span> </div> <a href="#" class="download-button"> <button>DOWNLOAD</button> </a> </div> {% endfor %} </div> {% else %} <em class="note">There are no orders in your store.</em> {% endif %} </div> {% endblock %}
分页实现方案
1. 后端View修改
通过请求的GET参数获取当前页码,调用Shopify API时传入分页参数,同时判断是否存在上一页/下一页,将分页信息传递给模板:
import shopify from shopify_app.decorators import shop_login_required from django.shortcuts import render @shop_login_required def index(request): # 获取当前页码,默认第1页 current_page = int(request.GET.get('page', 1)) # 设置每页显示的订单数量,可根据需求调整 per_page = 20 # 调用Shopify API获取指定页的订单 orders = shopify.Order.find(status='any', page=current_page, limit=per_page) # 判断是否存在上一页和下一页 prev_page = current_page - 1 if current_page > 1 else None # 如果返回的订单数量等于per_page,说明可能还有下一页 next_page = current_page + 1 if len(orders) == per_page else None # 将订单和分页信息传递给模板 return render(request, 'home/index.html', { 'orders': orders, 'prev_page': prev_page, 'next_page': next_page })
2. 前端模板修改
根据后端传递的分页参数,动态渲染可点击的分页链接,无分页时禁用对应按钮:
{% extends "base.html" %} {% load template_tags %} {% block content %} <div id="orders"> <div style="display: flex;"> <h2 style="width: 50%;">Your recent orders</h2> </div> {% if orders %} <div class="order-list"> <p id="page-toggle"> <!-- 上一页按钮 --> {% if prev_page %} <a href="?page={{ prev_page }}"> <span id="prev-page">< <b>PREV PAGE</b> </span> </a> {% else %} <span id="prev-page" style="opacity: 0.5; pointer-events: none;">< <b>PREV PAGE</b> </span> {% endif %} <!-- 下一页按钮 --> {% if next_page %} <a href="?page={{ next_page }}"> <span id="next-page"> <b>NEXT PAGE</b>> </span> </a> {% else %} <span id="next-page" style="opacity: 0.5; pointer-events: none;"> <b>NEXT PAGE</b>> </span> {% endif %} </p> {% for order in orders %} <div class="order box"> <div class="wrapper"> <a style='width: 25%; color: black;' href="https://{{ current_shop.domain }}/admin/orders/{{ order.id }}" target="_blank">{{ order.name }}</a> <span style='width: 25%;'>{{ order.created_at | convert_str_date }}</span> <span style='width: 25%;'>{{ order.total_price }} {{ order.currency }}</span> <span style='width: 25%;'>From: {{ order.billing_address.name }}</span> </div> <a href="#" class="download-button"> <button>DOWNLOAD</button> </a> </div> {% endfor %} </div> {% else %} <em class="note">There are no orders in your store.</em> {% endif %} </div> {% endblock %}
补充说明
如果需要严格遵循Shopify API返回的分页链接,可以解析API响应头中的Link字段获取官方的上一页/下一页URL,替换上述代码中判断prev_page和next_page的逻辑:
response_headers = shopify.ShopifyResource.connection.response.headers prev_page = None next_page = None if 'Link' in response_headers: links = response_headers['Link'].split(',') for link in links: if 'rel="prev"' in link: prev_page = link.split(';')[0].strip('<>').split('page=')[1] elif 'rel="next"' in link: next_page = link.split(';')[0].strip('<>').split('page=')[1]
这种方式可以确保分页逻辑和Shopify API的官方分页完全一致,但需要注意URL解析的兼容性。
内容的提问来源于stack exchange,提问作者royalsanga
相关产品推荐
相关产品推荐

