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

Django应用在Apache与开发服务器中编码不一致问题排查

环境配置
  • Django: 4.0.5
  • Python: 3.9.2
  • Debian: 11.1
  • Apache2: 2.4.53-1~deb11u1
  • libapache2-mod-wsgi-py3: 4.7.1-3+b1
  • mariadb-server-10.5: 1:10.5.15-0+deb11u1
问题现象

同一代码在开发服务器中运行无报错,但部署到Apache2后,执行以下代码时出现编码错误:

strx = 'sth %s' % name
f = open('/tmp/somerandomfile', 'w')
f.write(strx)

其中name变量来自数据库,包含本国语言字符。

两个环境下的输出差异:

  • 开发服务器控制台输出:
    print(strx, type(strx))
    Kiadások <class 'str'>
    
  • Apache日志输出:
    print(strx, type(strx))
    Kiad\xc3\xa1sok <class 'str'>
    

开发服务器返回200状态码,Apache则抛出错误:

UnicodeEncodeError: 'ascii' codec can't encode character '\\xe1' in position 5: ordinal not in range(128)
关键差异发现

查看文件对象的编码属性,发现核心差异:

  • 开发服务器:
    'f': <_io.TextIOWrapper name='/tmp/tmplnrhh7np' mode='w' encoding='UTF-8'>
    
  • Apache环境:
    'f': <_io.TextIOWrapper name='/tmp/tmpw3jl3sk2' mode='w' encoding='ANSI_X3.4-1968'>
    

Apache创建文件时默认使用ANSI_X3.4-1968(即ASCII)编码,导致无法写入非ASCII字符。

相关配置文件

Apache站点配置(sites-enabled/gyuser.conf)

<VirtualHost *:80>

ServerName 127.0.0.25
ServerAlias Servernames
DocumentRoot /usr/share/gyuser

<Directory /usr/share/gyuser>
    Order allow,deny
    Allow from all
</Directory>

WSGIDaemonProcess gyuser.djangoserver user=gyuser processes=10 threads=20 display-name=%{GROUP} python-path=/usr/share/gyuser:/home/gyuser/.virtualenvs/gyuser/lib/python3.9/site-packages

WSGIProcessGroup gyuser.djangoserver

WSGIScriptAlias / /usr/share/gyuser/gyuser/wsgi.py
CustomLog ${APACHE_LOG_DIR}/gyuser-access.log combined
ErrorLog ${APACHE_LOG_DIR}/gyuser-error.log
LogLevel debug

wsgi.py代码

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gyuser.settings")

application = get_wsgi_application()
问题原因

Python的默认文件编码由系统环境变量决定:

  • 开发服务器在终端环境运行,终端的LANG/LC_ALL等变量设置为UTF-8,Python继承该配置,因此默认用UTF-8打开文件。
  • Apache的WSGI守护进程运行时,未加载用户的locale配置,默认使用ASCII编码(ANSI_X3.4-1968),导致写入含非ASCII字符的字符串时触发编码错误。
解决方法

方法1:显式指定文件编码(最稳妥)

打开文件时直接指定encoding='utf-8',不依赖环境配置:

f = open('/tmp/somerandomfile', 'w', encoding='utf-8')

方法2:配置Apache WSGI进程的locale环境

在Apache的WSGIDaemonProcess指令中添加env参数,指定UTF-8编码的locale(以匈牙利语hu_HU.UTF-8为例,可根据实际语言调整):

WSGIDaemonProcess gyuser.djangoserver user=gyuser processes=10 threads=20 display-name=%{GROUP} python-path=/usr/share/gyuser:/home/gyuser/.virtualenvs/gyuser/lib/python3.9/site-packages env=LANG=hu_HU.UTF-8

修改后重启Apache生效:systemctl restart apache2

方法3:在wsgi.py中设置环境变量

在wsgi.py开头添加环境变量设置,强制指定UTF-8 locale:

import os
# 设置UTF-8 locale
os.environ['LANG'] = 'hu_HU.UTF-8'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "gyuser.settings")

from django.core.wsgi import get_wsgi_application

application = get_wsgi_application()

补充:确保系统已安装对应locale

执行locale -a查看系统已安装的locale,如果目标locale(如hu_HU.UTF-8)不存在,运行以下命令安装:

dpkg-reconfigure locales

在弹出的界面中勾选对应locale并确认。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 12:54:19