python - 为什么当 quizform.ans1 在访问动态创建的表单时工作时 getattr(quizform, 'ans1' ) 会失败?

标签 python django django-forms

我正在生成一个测验答案表格。由于每个测验的答案都会不同,因此我根据测验创建一个动态表单。测验存储在字典中。

我正在创建表单字段:

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/

相关文章:

django - 如何向 Django 表单小部件添加额外的上下文

python - 评估 LightFM 推荐模型

python - 删除 pandas 列内的部分字符串

django - 测试链接是否指向 Django 中的正确页面

python - 导入错误 : cannot import name force_text

django - 单个 View 中的多个 Django 表单 : Why Does One POST Clear Other Forms?

python - 是什么让 C 比 Python 更快?

python - 用 C 解释来自 Modbus ASCII 的数据

django - Django Rest Framework ModelViewSet 上的删除方法

django - 如何使用modelform和multiwidget