我需要根据用户是否登录来创建一个可能有或没有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
定义中添加等效代码。
有人能想出一个很好的方法吗?
答案 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元素,以允许您根据视图请求上下文排除/包含字段。除此之外非常有用的功能。
答案 2 :(得分:0)
嗯,遗憾的是django-floppyforms没有提供对请求的访问权限。很高兴知道它是一个选项,因为我最近开始在我自己的项目中使用django-floppyforms。
除此之外,我能想到的最好的事情就是简单地依赖模板继承。您可以创建comments/form.html
文件,然后让每个comments/*/form.html
扩展该文件。把Recaptcha代码放在基础form.html
中,你就可以了。
答案 3 :(得分:0)
我对条件字段所做的是拥有一个基类(继承自Form
)和其他带有额外条件字段的子类。
然后在我看来,根据条件,我选择了所需的子类形式。我知道它涉及一些重复的代码,但它似乎比其他方法更容易。