5

我需要根据用户是否登录来创建一个可能有或没有 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

4 回答 4

5

我假设您在视图中实例化您的表单,因此您可以将用户从请求传递到表单(就像在 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()
于 2012-06-07T17:35:23.513 回答
3

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

这是相关的文档部分。

于 2012-06-07T17:51:44.147 回答
1

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

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

于 2013-03-23T05:02:26.607 回答
0

好吧,不幸的是 django-floppyforms 不能访问请求。很高兴知道这是一个选项,因为我最近开始在我自己的项目中使用 django-floppyforms。

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

于 2012-06-06T21:28:02.077 回答