You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取GEOSGeometry对象时触发DjangoUnicodeDecodeError的解决求助

解决Django GIS读取含非拉丁语系UTF-8字符串Shapefile的Unicode解码错误

你遇到的问题核心是GDAL自动检测的Shapefile编码与实际编码不匹配——处理波斯语这类非拉丁语系字符时,GDAL经常会误判.dbf文件的编码,导致Django的force_text方法用错误编码解码字节,触发DjangoUnicodeDecodeError。下面给你几个可行的解决方案,按推荐程度排序:

1. 手动指定Shapefile的编码读取

这是最直接的解决方案,先确认你的Shapefile实际使用的编码(波斯语常用Windows-1256,也可能是UTF-8但GDAL未正确识别),然后在初始化DataSource时显式指定编码:

from django.contrib.gis.gdal import DataSource

# 替换为你Shapefile的实际编码,比如Windows-1256
ds = DataSource(shp_file_path, encoding='Windows-1256')
lyr = ds[0]
for feat in lyr:
    geom_t = feat.geom.transform(wgs84, clone=True)
    name = feat.get('name')  # 现在能正确解码字段内容

如果你不确定编码,可以用GDAL的ogrinfo命令检测:

ogrinfo -so your_shapefile.shp

也可以尝试波斯语常见编码(Windows-1256、UTF-8)逐个测试。

2. 手动解码原始字节数据

如果指定编码仍无效,你可以绕过Django的自动解码逻辑,直接获取字段的原始字节,再用正确编码解码:

for feat in lyr:
    geom_t = feat.geom.transform(wgs84, clone=True)
    # 加上raw=True获取原始字节,避免Django自动解码出错
    name_raw = feat.get('name', raw=True)
    # 用实际编码解码,比如Windows-1256
    name = name_raw.decode('Windows-1256')
    
    # 若不确定编码,可临时用错误忽略模式应急(不推荐长期使用)
    # name = name_raw.decode('utf-8', errors='replace')

3. 临时修补Django的GDAL字段处理逻辑(不推荐)

如果前两种方法都无法解决,你可以临时修改Django源码(注意:升级Django后该改动会失效):
找到报错文件D:\Python\Python36\lib\site-packages\django\contrib\gis\gdal\field.py,修改as_string方法:

将原代码:

return force_text(string, encoding=self._feat.encoding, strings_only=True)

替换为:

# 强制指定正确编码,比如Windows-1256,同时增加错误处理
return force_text(string, encoding='Windows-1256', errors='replace', strings_only=True)

此方法仅作为临时应急方案,不推荐长期依赖,建议优先使用前两种方法从根源解决问题。

内容的提问来源于stack exchange,提问作者Majid Hojati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:44:01