Django多对多关联模型导出CSV如何获取两个模型的多个字段
解决方案
核心逻辑:多对多关联对象支持读取所有字段,你只需要按需读取你需要的dbmobile字段即可,以下是两种常用的导出方案:
方案1:单条expense记录对应一行,多关联对象值用逗号分隔
适合希望expense数据不重复、关联用户信息合并展示的场景。
优化点说明
- 用
prefetch_related提前加载多对多关联数据,大幅减少数据库查询次数 - 修复原代码中列表推导式变量名覆盖外层expense对象的bug
- 支持导出
dbmobile任意字段
修改后完整views.py代码
import csv from django.http import HttpResponse from .models import expense def export_csv(request): response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="file.csv"' # 预加载多对多关联的user数据,避免N+1查询 expenses = expense.objects.prefetch_related('user').all() writer = csv.writer(response) # 按需添加你需要导出的dbmobile字段列名 writer.writerow(['日期', '含税金额', '不含税金额', '关联用户姓名', '关联用户ID', '关联用户手机号', '关联站点编码']) for e in expenses: # 分别提取dbmobile的多个字段,各自拼接为逗号分隔的字符串 user_names = ', '.join([u.User_Name for u in e.user.all()]) user_ids = ', '.join([u.User_id for u in e.user.all()]) user_mobiles = ', '.join([u.Mobile_Number for u in e.user.all()]) site_codes = ', '.join([u.Site_Code for u in e.user.all()]) # 写入所有需要的字段 writer.writerow([ e.Date, e.IncludeTax, e.ExcludeTax, user_names, user_ids, user_mobiles, site_codes ]) return response
方案2:单条expense+单条关联user对应一行,无合并值
适合希望每条数据对应一组expense+user关系、不需要逗号拼接的场景,导出后可以直接做数据透视分析。
核心代码示例
只需要修改循环写入的逻辑即可:
for e in expenses: # 处理没有关联用户的情况 if not e.user.exists(): writer.writerow([e.Date, e.IncludeTax, e.ExcludeTax, '', '', '', '']) else: # 每个关联用户单独写一行,expense字段复用 for u in e.user.all(): writer.writerow([ e.Date, e.IncludeTax, e.ExcludeTax, u.User_Name, u.User_id, u.Mobile_Number, u.Site_Code ])
内容的提问来源于stack exchange,提问作者sshell
相关产品推荐
相关产品推荐

