我正在使用 Django 来管理 Postgres 数据库。我有一个值存储在代表西班牙(马拉加)的一个城市的数据库中。我的 Django 项目通过将 unicode 字符串放在from __future__ import unicode_literals
我创建的每个文件的开头来处理所有内容。
我需要从数据库中提取城市信息并使用XML
请求将其发送到另一台服务器。一路上有日志记录,以便我可以观察数据流。当我尝试记录城市的值时,我得到以下回溯:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 1: ordinal not in range(128)
这是我用来记录我传递的值的代码。
def createXML(self, dict):
"""
.. method:: createXML()
Create a single-depth XML string based on a set of tuples
:param dict: Set of tuples (simple dictionary)
"""
xml_string = ''
for key in dict:
self.logfile.write('\nkey = {0}\n'.format(key))
if (isinstance(dict[key], basestring)):
self.logfile.write('basestring\n')
self.logfile.write('value = {0}\n\n'.format(dict[key].decode('utf-8')))
else:
self.logfile.write('value = {0}\n\n'.format(dict[key]))
xml_string += '<{0}>{1}</{0}>'.format(key, dict[key])
return xml_string
我基本上将我拥有的所有信息保存在一个简单的字典中,并使用这个函数来生成一个XML
格式化的字符串——这超出了这个问题的范围。
我得到的错误让我想知道数据库中实际保存的是什么。我已验证该值已utf-8
编码。我创建了一个简单的脚本来从数据库中提取值,对其进行解码并将其打印到屏幕上。
from __future__ import unicode_literals
import psycopg2
# Establish the database connection
try:
db = psycopg2.connect("dbname = 'dbname' \
user = 'user' \
host = 'IP Address' \
password = 'password'")
cur = db.cursor()
except:
print "Unable to connect to the database."
# Get database info if any is available
command = "SELECT state FROM table WHERE id = 'my_id'"
cur.execute(command)
results = cur.fetchall()
state = results[0][0]
print "my state is {0}".format(state.decode('utf-8'))
结果:my state is Málaga
在 Django 中,我正在执行以下操作来创建 HTTP 请求:
## Create the header
http_header = "POST {0} HTTP/1.0\nHost: {1}\nContent-Type: text/xml\nAuthorization: Basic {2}\nContent-Length: {3}\n\n"
req = http_header.format(service, host, auth, len(self.xml_string)) + self.xml_string
谁能帮我纠正问题,以便我可以将此信息写入数据库并能够创建req
要发送到其他服务器的字符串?
由于 Django 的处理方式,我是否收到此错误?如果是这样,Django 在做什么?或者,我告诉 Django 这样做是为了什么?
EDIT1:我也尝试django.utils.encoding
在这个状态值上使用 Django。我从saltycrane中读到了一些关于 Djano 可能会遇到 unicode/utf-8 的问题。
我试图修改我的日志记录以使用该smart_str
功能。
def createXML(self, dict):
"""
.. method:: createXML()
Create a single-depth XML string based on a set of tuples
:param dict: Set of tuples (simple dictionary)
"""
xml_string = ''
for key in dict:
if (isinstance(dict[key], basestring)):
if (key == 'v1:State'):
var_str = smart_str(dict[key])
for index in range(0, len(var_str)):
var = bin(ord(var_str[index]))
self.logfile.write(var)
self.logfile.write('\n')
self.logfile.write('{0}\n'.format(var_str))
xml_string += '<{0}>{1}</{0}>'.format(key, dict[key])
return xml_string
这样做我可以将正确的值写入日志,但我缩小了.format()
Python 中字符串功能的另一个可能问题。当然,我的 Google 搜索的python format unicode
第一个结果是Issue 7300,它指出这是 Python 2.7 的一个已知“问题”。
现在,从另一个 stackoverflow 帖子中,我发现了一个“解决方案”,它在 Django 中无法使用该smart_str
功能(或者至少我无法让它们一起工作)。
我将继续挖掘,看看我是否找不到潜在的问题 - 或者至少找不到解决方法。
.format()
EDIT2:我通过简单地连接字符串而不是使用该功能找到了一种解决方法。我不喜欢这个“解决方案”——它很丑,但它完成了工作。
def createXML(self, dict):
"""
.. method:: createXML()
Create a single-depth XML string based on a set of tuples
:param dict: Set of tuples (simple dictionary)
"""
xml_string = ''
for key in dict:
xml_string += '<{0}>'.format(key)
if (isinstance(dict[key], basestring)):
xml_string += smart_str(dict[key])
else:
xml_string += str(dict[key])
xml_string += '<{0}>'.format(key)
return xml_string
我将不回答这个问题,因为我很想找到一个解决方案,让我.format()
按照预期的方式使用它。