Django: FieldError 无法将关键词 '___' 解析为字段
我遇到了一个 FieldError
错误。
我有一个模型:
class Foo(models.Model):
__bar = models.TextField(default=lambda: cPickle.dumps(set()), primary_key=True)
def get_bar(self):
return cPickle.loads(str(self.__bar))
def set_bar(self, values):
self.__bar = cPickle.dumps(values)
bar = property(get_bar, set_bar)
我在 admin.py 中注册了它:
admin.site.register(Foo)
当我运行服务器并访问 /admin 时,我在列表中看到了 Foo。如果我点击“添加”,一切正常,会显示一个表单来添加新的 Foo。但是,如果我点击“保存并添加另一个”或者“更改”或“Foos”,我就会遇到 FieldError
错误。
FieldError at /admin/appname/Foo/
Cannot resolve keyword '_Foo' into field. Choices are: _Foo__bar, appname
错误追踪信息是:
环境:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/appname/foo/
Django Version: 1.2.4
Python Version: 2.6.6
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'pagination',
'apps.appname']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'pagination.middleware.PaginationMiddleware')
Traceback:
File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
100. response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in wrapper
265. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
76. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
78. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py" in inner
190. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapper
21. return decorator(bound_func)(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in _wrapped_view
76. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/utils/decorators.py" in bound_func
17. return func(self, *args2, **kwargs2)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/options.py" in changelist_view
1097. 'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py" in __len__
80. self._result_cache = list(self.iterator())
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py" in iterator
271. for row in compiler.results_iter():
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py" in results_iter
677. for rows in self.execute_sql(MULTI):
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py" in execute_sql
722. sql, params = self.as_sql()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py" in as_sql
57. ordering, ordering_group_by = self.get_ordering()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py" in get_ordering
346. self.query.model._meta, default_order=asc):
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/compiler.py" in find_ordering_name
375. opts, alias, False)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py" in setup_joins
1215. "Choices are: %s" % (name, ", ".join(names)))
Exception Type: FieldError at /admin/appname/foo/
Exception Value: Cannot resolve keyword '_Foo' into field. Choices are: _Foo__bar, appname
这可能是什么原因呢?我查了一下,发现了一些类似的错误,但它们似乎和多对多字段有关,而我没有使用这样的字段。还有其他模型引用了这个模型作为外键,但这似乎不太可能导致这个问题。
1 个回答
5
因为你在 __bar
前面加了两个下划线,Python会对这个名字进行处理(文档链接),试图让这个变量变得“私有”,也就是不想让外部随便访问。
其实在Python中并没有真正的私有变量,但通过使用双下划线的方式,你让Python把 __bar
重新格式化成 _(classname)__bar
,所以Django会告诉你“可选项是: _Foo__bar
...”。
如果你想表示 bar
不应该在类外使用,我建议你使用单下划线的方式(在上面的链接中也有讨论),这样可以解决你遇到的问题,因为单下划线前缀不会被处理成其他名字。