如何在django-pandas DataFrame中获取模型所有外键的字符串值
问题原因
三个场景异常的核心原因有三点:
- 跨表字段路径写错:你的三个外键都自定义了
to_field参数,关联的是对应表的state_name/district_name/block_name字符串字段,不是默认自增id,关联表上也不存在名为name的字段,场景2里写的state_name__name是无效字段路径,QuerySet返回结果里没有对应值,自然全返回NaN。 .values()默认行为限制:直接调用无参数的.values()只会返回当前模型表的本地存储字段,不会自动跨表拉取关联表数据,就算传了跨表字段路径也不会被识别填充。- 直接传外键字段名报错的原因:django-pandas处理外键字段时,默认会按数字主键类型做校验,你自定义
to_field为字符串类型,和框架默认预期的字段类型不匹配,就会抛出ValueError。
正确实现方法
不要调用无参数的.values(),直接在原始QuerySet上调用to_dataframe,写对跨表字段路径即可:
- 外键关联id值的路径是
{外键字段名}_id,比如state_name_id,和你之前用的state_name__id效果一致 - 你需要的外键对应字符串名称,路径是
{外键字段名}__{关联表目标字段名},因为你to_field设的是关联表的同名字符串字段,所以路径就是state_name__state_name、district_name__district_name、block_name__block_name
正确代码示例:
# 不要加无参数的.values(),直接用模型QuerySet fetch_whole_database = GroupDetail.objects.all() fetch_data_df = fetch_whole_database.to_dataframe( [ 'unit_type', 'state_name__state_name', # 取State表的state_name字符串值 'unit_name', 'district_name__district_name', # 取District表的district_name字符串值 'block_name__block_name', # 取Block表的block_name字符串值 'village_name', 'village_covered_through_whatsapp_group', 'number_of_whatsapp_group_created', 'number_of_farmers_covered_in_the_village' ], index='id' )
如果觉得双下划线的列名不便于后续处理,可以在QuerySet里先用annotate给字段起别名,再转DataFrame:
from django.db.models import F fetch_whole_database = GroupDetail.objects.annotate( state_str=F('state_name__state_name'), district_str=F('district_name__district_name'), block_str=F('block_name__block_name') ) fetch_data_df = fetch_whole_database.to_dataframe( [ 'unit_type', 'state_str', 'unit_name', 'district_str', 'block_str', 'village_name', 'village_covered_through_whatsapp_group', 'number_of_whatsapp_group_created', 'number_of_farmers_covered_in_the_village' ], index='id' )
额外注意点
你模型里的__str__方法写法错误,Python函数只会执行第一个return语句,后面的所有return都不会生效,当前__str__永远只会返回unit_type的值,后续多余的return代码可以直接删掉,按需保留一个你需要的返回值即可。
内容的提问来源于stack exchange,提问作者Abhilash Singh Chauhan
相关产品推荐
相关产品推荐

