如何在Vuetify数据表中展示第二个API响应并合并双接口数据
当然可以合并两个API的响应数据在同一张表格展示,推荐两种实现方案,按需选择:
方案一:后端优化接口(优先推荐)
这种方式能减少前端请求次数,避免分页逻辑混乱,性能更优。
- 修正序列化器,关联Package和Module
原PackageSerializer存在字段错误(模型里是package_name而非name),同时添加关联的Module数据:
class ModulesSerializer(serializers.ModelSerializer): class Meta: model = module fields = ('id', 'name') class PackageSerializer(serializers.ModelSerializer): # 通过source关联Module集合,模型未定义related_name时默认用`module_set` modules = ModulesSerializer(many=True, source='module_set', read_only=True) class Meta: model = package fields = ('id', 'package_name', 'modules')
- 优化Package列表视图,预加载关联数据
使用prefetch_related避免N+1查询,一次性返回Package及对应Module:
def list_packages(request): paginator = PageNumberPagination() paginator.page_size = 20 # 预加载关联的Module数据,提升查询性能 packages = package.objects.filter(portfolio=request.data['portfolio']).prefetch_related('module_set').order_by('id') paginate = paginator.paginate_queryset(packages, request) serializer = PackageSerializer(paginate, many=True) return paginator.get_paginated_response(serializer.data)
- 前端直接渲染嵌套数据
只需要调用getPackages(),在v-data-table中嵌套展示Module:
<v-data-table :items="packages"> <template v-slot:items="props"> <td>{{ props.item.package_name }}</td> <td> <v-list dense> <v-list-item v-for="module in props.item.modules" :key="module.id"> {{ module.name }} </v-list-item> </v-list> </td> </template> </v-data-table>
方案二:前端合并数据(临时场景用)
如果不想修改后端,可以在前端获取Package后,逐个请求对应Module并合并数据,但这种方式会触发多次API请求,分页场景下性能较差:
- 修改前端请求逻辑,合并数据
async getPackages(){ var data={"portfolio":this.filter_portfolio} var url = this.page ? '/projects/list_packages?page='+this.page : '/home' try { const response = await this.$axios.$post(url, data, config) if(response){ this.packages = response.results // 遍历每个Package,请求对应的Module并挂载到对象上 for(const pkg of this.packages){ const moduleRes = await this.$axios.$post('/projects/list_modules', {"package": pkg.id}, config) pkg.modules = moduleRes.results } } } catch(e) { // 错误处理逻辑 } },
- 表格渲染同方案一
额外注意点
- 原
list_modules视图中,package=package.objects.filter(...)这行代码未被使用,可删除。 - 如果需要将Package和Module作为平级行展示(比如一行Package、一行Module),可以在前端把数据扁平化为一维数组:
let mergedData = [] this.packages.forEach(pkg => { mergedData.push({ type: 'package', name: pkg.package_name }) pkg.modules.forEach(mod => { mergedData.push({ type: 'module', name: mod.name }) }) }) // 表格绑定mergedData即可
内容的提问来源于stack exchange,提问作者user20408044
相关产品推荐
相关产品推荐

