表示用户集合
除了使用单个资源表示形式外,此 API 还需要一组用户的表示。 例如客户请求用户或粉丝列表时使用的格式。 以下是一组用户的表示:
{
"items": [
{ ... user resource ... },
{ ... user resource ... },
...
],
"_meta": {
"page": 1,
"per_page": 10,
"total_pages": 20,
"total_items": 195
},
"_links": {
"self": "http://localhost:5000/api/users?page=1",
"next": "http://localhost:5000/api/users?page=2",
"prev": null
}
}
在这个表示中, items
是用户资源的列表,每个用户资源的定义如前一节所述。 _meta
部分包含集合的元数据,客户端在向用户渲染分页控件时就会用得上。 _links
部分定义了相关链接,包括集合本身的链接以及上一页和下一页链接,也能帮助客户端对列表进行分页。
由于分页逻辑,生成用户集合的表示很棘手,但是该逻辑对于我将来可能要添加到此 API 的其他资源来说是一致的,所以我将以通用的方式实现它,以便适用于其他模型。 可以回顾 第十六章 ,就会发现我目前的情况与全文索引类似,都是实现一个功能,还要让它可以应用于任何模型。 对于全文索引,我使用的解决方案是实现一个 SearchableMixin
类,任何需要全文索引的模型都可以从中继承。 我会故技重施,实现一个新的 mixin 类,我命名为 PaginatedAPIMixin
:
app/models.py :分页表示 mixin 类。
class PaginatedAPIMixin(object):
@staticmethod
def to_collection_dict(query, page, per_page, endpoint, **kwargs):
resources = query.paginate(page, per_page, False)
data = {
'items': [item.to_dict() for item in resources.items],
'_meta': {
'page': page,
'per_page': per_page,
'total_pages': resources.pages,
'total_items': resources.total
},
'_links': {
'self': url_for(endpoint, page=page, per_page=per_page,
**kwargs),
'next': url_for(endpoint, page=page + 1, per_page=per_page,
**kwargs) if resources.has_next else None,
'prev': url_for(endpoint, page=page - 1, per_page=per_page,
**kwargs) if resources.has_prev else None
}
}
return data
to_collection_dict()
方法产生一个带有用户集合表示的字典,包括 items
, _meta
和 _links
部分。 你可能需要仔细检查该方法以了解其工作原理。 前三个参数是 Flask-SQLAlchemy 查询对象,页码和每页数据数量。 这些是决定要返回的条目是什么的参数。 该实现使用查询对象的 paginate()
方法来获取该页的条目,就像我对主页,发现页和个人主页中的用户动态所做的一样。
复杂的部分是生成链接,其中包括自引用以及指向下一页和上一页的链接。 我想让这个函数具有通用性,所以我不能使用类似 url_for('api.get_users', id=id, page=page)
这样的代码来生成自链接(译者注:因为这样就固定成用户资源专用了)。 url_for()
的参数将取决于特定的资源集合,所以我将依赖于调用者在 endpoint
参数中传递的值,来确定需要发送到 url_for()
的视图函数。 由于许多路由都需要参数,我还需要在 kwargs
中捕获更多关键字参数,并将它们传递给 url_for()
。 page
和 per_page
查询字符串参数是明确给出的,因为它们控制所有 API 路由的分页。
这个 mixin 类需要作为父类添加到 User 模型中:
app/models.py :添加 PaginatedAPIMixin 到 User 模型中。
class User(PaginatedAPIMixin, UserMixin, db.Model):
# ...
将集合转换成 json 表示,不需要反向操作,因为我不需要客户端发送用户列表到服务器。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论