因为我们需要我们的ModelChoiceFields根据它们的使用位置有不同的(非__unicode__
)标签,我认为覆盖ModelChoiceField并使其接受一个额外的参数将是一个明智的想法。被调用而不是label_from_instance。我可以为我们需要的每个实例创建一个子类,但这不是真的干,现在是吗?
我的新ModelChoiceField:
import django.forms
class ModelChoiceField(django.forms.ModelChoiceField):
"""Subclasses Django's ModelChoiceField and adds one parameter, `obj_label`.
This should be a callable with one argument (the current object) which
returns a string to use as the label of that object or instance."""
def __init__(self, obj_label=None, *args, **kwargs):
super(django.forms.ModelChoiceField, self).__init__(*args, **kwargs)
self.obj_label = obj_label
def label_from_instance(self, obj):
if self.obj_label:
return self.label(obj)
return super(django.forms.ModelChoiceField, self).label_from_instance(obj)
似乎简单易行。我只对名为obj_label
的参数感兴趣,并将所有其余参数传递给ModelChoiceField的__init__
函数。或者我想。 Python现在抱怨__init__
获得意外的关键字参数......我这样称呼它:nationality = ModelChoiceField(queryset=Country.objects.all(), obj_label=lambda x: x.name(), empty_label=None)
,错误是:
Traceback:
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
103. resolver_match = resolver.resolve(request.path_info)
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
321. sub_match = pattern.resolve(new_path)
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
321. sub_match = pattern.resolve(new_path)
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/urlresolvers.py" in resolve
223. return ResolverMatch(self.callback, args, kwargs, self.name)
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/urlresolvers.py" in callback
230. self._callback = get_callable(self._callback_str)
File "/home/patrick/spng/lib/python2.7/site-packages/django/utils/functional.py" in wrapper
29. result = func(*args)
File "/home/patrick/spng/lib/python2.7/site-packages/django/core/urlresolvers.py" in get_callable
97. mod = import_module(mod_name)
File "/home/patrick/spng/lib/python2.7/site-packages/django/utils/importlib.py" in import_module
35. __import__(name)
File "/home/patrick/spng/src/internship/views.py" in <module>
40. from resume.views import assemble_dict_list
File "/home/patrick/spng/src/resume/views.py" in <module>
20. from resume.forms import (HobbyForm, LanguageForm, EducationForm,
File "/home/patrick/spng/src/resume/forms.py" in <module>
29. class NationalityForm(forms.ModelForm):
File "/home/patrick/spng/src/resume/forms.py" in NationalityForm
31. nationality = ModelChoiceField(queryset=Country.objects.all(), obj_label=lambda x: x.nationality(), empty_label=None)
File "/home/patrick/spng/src/stageplaza_ng/fields.py" in __init__
11. super(django.forms.ModelChoiceField, self).__init__(*args, **kwargs)
File "/home/patrick/spng/lib/python2.7/site-packages/django/forms/fields.py" in __init__
672. initial=initial, help_text=help_text, *args, **kwargs)
Exception Type: TypeError at /stagiaires/overzicht/
Exception Value: __init__() got an unexpected keyword argument 'queryset'
这可能是非常愚蠢的事情,所以有人有想法吗?
答案 0 :(得分:4)
重命名除ModelChoiceField以外的类,请注意剩下的逻辑
class CustomModelChoiceField(django.forms.ModelChoiceField):
"""Subclasses Django's ModelChoiceField and adds one parameter, `obj_label`.
This should be a callable with one argument (the current object) which
returns a string to use as the label of that object or instance."""
def __init__(self, obj_label=None, *args, **kwargs):
super(CustomModelChoiceField, self).__init__(*args, **kwargs)
self.obj_label = obj_label
def label_from_instance(self, obj):
if self.obj_label:
return self.label(obj)
return super(CustomModelChoiceField, self).label_from_instance(obj)
答案 1 :(得分:0)
事实证明这真的很愚蠢。我在超级电话中调用了Django ModelChoiceField super。像这样:super(django.forms.ModelChoiceField, self).__init__(*args, **kwargs)
。在这种情况下,我得到这个例外是完全合理的。 ModelChoiceField super是ChoiceField。该类不接受名称为queryset
的关键字参数。
事实上,我应该称之为当前班级的超级。像这样:super(ModelChoiceField, self).__init__(*args, **kwargs)
。这是文档中的很多次,但这次我有点想念它。 ModelChoiceField的正确覆盖是:
import django.forms
class ModelChoiceField(django.forms.ModelChoiceField):
"""Subclasses Django's ModelChoiceField and adds one parameter, `obj_label`.
This should be a callable with one argument (the current object) which
returns a string to use as the label of that object or instance."""
def __init__(self, obj_label=None, *args, **kwargs):
super(ModelChoiceField, self).__init__(*args, **kwargs)
self.obj_label = obj_label
def label_from_instance(self, obj):
if self.obj_label:
return self.label(obj)
return super(ModelChoiceField, self).label_from_instance(obj)
这很有效。但我不得不部分同意斯里尼瓦斯的回答。重命名为ModelChoiceField更清楚,因此可以立即清楚发生了什么。