表格中的条件字段

时间:2012-06-06 20:15:57

标签: django django-forms

我需要根据用户是否登录来创建一个可能有或没有ReCaptcha字段的Form类。

因为这是一个CommentForm,所以我无法访问表单创建/定义中的request对象,所以我不能依赖它。

对于POST请求,解决方案很简单:我有这个:

class ReCaptchaCommentForm(CommentForm):
    def __init__(self, data=None, *args, **kwargs):
        super(ReCaptchaCommentForm, self).__init__(data, *args, **kwargs)
        if data and 'recaptcha_challenge_field' in data:
            self.fields['captcha'] = ReCaptchaField()

完成此操作后,表单验证应按预期工作。现在问题出在模板方面。我需要模板如下:

<form action={% comment_form_target %} method="post">
{# usual form stuff #}
{% if not user.is_authenticated %}
<script  type="text/javascript"
         src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<div id="recaptcha-div"></div>
<script type="text/javascript">
  Recaptcha.create({{ public_key }}, "recaptcha-div",
                   { theme: 'white',
                     callback: Recaptcha.focus_response_field });
</script>
{% endif %}
</form>

但我不想在每个comments/*/form.html模板上重复该代码。我认为应该有一些方法可以从小部件的render方法和Media定义中添加等效代码。

有人能想出一个很好的方法吗?

4 个答案:

答案 0 :(得分:4)

我假设您在视图中设置表单,因此您可以将用户从请求传递到表单(就像在auth app SetPassword表单中一样):

def __init__(self, user, data=None, *args, **kwargs):
    super(ReCaptchaCommentForm, self).__init__(data, *args, **kwargs)
    if user.is_authenticated():
        self.fields['captcha'] = ReCaptchaField()

答案 1 :(得分:3)

使用crispy-forms! 您可以在表单布局中包含html元素,以允许您根据视图请求上下文排除/包含字段。除此之外非常有用的功能。

Here's the relevant doc section.

答案 2 :(得分:0)

嗯,遗憾的是django-floppyforms没有提供对请求的访问权限。很高兴知道它是一个选项,因为我最近开始在我自己的项目中使用django-floppyforms。

除此之外,我能想到的最好的事情就是简单地依赖模板继承。您可以创建comments/form.html文件,然后让每个comments/*/form.html扩展该文件。把Recaptcha代码放在基础form.html中,你就可以了。

答案 3 :(得分:0)

我对条件字段所做的是拥有一个基类(继承自Form)和其他带有额外条件字段的子类。

然后在我看来,根据条件,我选择了所需的子类形式。我知道它涉及一些重复的代码,但它似乎比其他方法更容易。