为什么Django的reverse()在处理Unicode时失败?
这里有一个Django模型文件,它的表现并没有我预期的那样。
我本来希望to_url这个方法能在urls.py文件中进行反向查找,获取一个对应于用Arguments模型提供的参数调用那个视图的URL。
from django.db import models
class Element(models.Model):
viewname = models.CharField(max_length = 200)
arguments = models.ManyToManyField('Argument', null = True, blank = True )
@models.permalink
def to_url(self):
d = dict( self.arguments.values_list('key', 'value') )
return (self.viewname, (), d)
class Argument(models.Model):
key = models.CharField(max_length=200)
value = models.CharField(max_length=200)
最后,值d变成了一个从Unicode字符串到另一个Unicode字符串的字典。我认为,这样应该可以和permalink装饰器调用的reverse()方法正常工作,但结果却是:
TypeError: reverse() keywords must be strings
1 个回答
5
在你的 to_url
方法中,你需要确保 d
字典里的键不是 Unicode 字符串。这并不是 Django 特有的情况,而是 Python 中函数的关键字参数工作方式的一个特点。下面是一个简单的例子:
>>> def f(**kwargs): print kwargs
...
>>> d1 = { u'foo': u'bar' }
>>> d2 = { 'foo': u'bar' }
>>> f(**d1)
TypeError: f() keywords must be strings
>>> f(**d2)
{'foo': u'bar'}
把你的
d = dict( self.arguments.values_list('key', 'value') )
改成类似下面这样的
d = dict((str(k), v) for k, v in self.arguments.values_list('key', 'value').iteritems())
应该就能解决问题了。