我正在生成一个测验答案表格。由于每个测验的答案都会不同,因此我根据测验创建一个动态表单。测验存储在字典中。
我正在创建表单字段:
forms.py:
class QuizForm(forms.Form):
def __init__(self, quiz, *args, **kwargs):
super(QuizForm, self).__init__(*args, **kwargs)
chdict = {}
for num in range (1, 11):
ch = 'choices'+str(num)
chdict[ch] = []
for j in ('A', 'B', 'C', 'D'):
chstr = j + str(num)
chdict[ch].append((chstr, quiz[chstr]))
ansstr = 'ans'+str(num)
quesstr = 'ques'+str(num)
self.fields[ansstr] = forms.ChoiceField(label=quesstr, choices=chdict[ch], widget=forms.RadioSelect)
在模板中,我在测验表单上执行 getattr,这给出了 AttributeError:
template/quiz.html: <snippet>
{% for i in num %} <<< where num = ('1','2','3',...)
<post question>
{% with "ans"|add:i as ans %}
{{ quizform|getattribute:ans }} <<< I can access quizform.ans1 here directly, but getattr in template filter fails
{% endwith %}
{% endfor %}
getattribute 是一个模板过滤器:
@register.filter('getattribute')
def getattribute(f, name):
if hasattr(f, name): <<< I get AttributeError here.
return getattr(f, name)
else:
<error>
我是 django/python 新手,希望能得到一些帮助来调试它。
最佳答案
答案在于模板如何解析变量。模板 foo.bar
内部与 python foo.bar
中完全不同。模板查找语法实际上包装了一个稍微复杂的查找序列,它试图弄清楚您是否指的是字典查找、属性、可调用属性、数组索引等。
在模板中,当您直接编写 quizform.ans1
时,它会起作用,因为实际上最终会解析为字段 dict 上的字典查找。这是因为 django 表单定义了以下魔术方法:
def __getitem__(self, name):
"Returns a BoundField with the given name."
try:
field = self.fields[name]
except KeyError:
raise KeyError('Key %r not found in Form' % name)
return BoundField(self, field, name)
python __getitem__
魔术方法允许非字典类像字典一样工作。
长话短说...
@register.filter
def lookup(f, name):
try:
return f[name]
except KeyError:
return None
应该工作得更好,(我还没有确认)。请注意,我更改了过滤器的名称...旧名称并不真正合适,因为它现在导致字典而不是属性查找。
关于python - 为什么当 quizform.ans1 在访问动态创建的表单时工作时 getattr(quizform, 'ans1' ) 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9827023/