我正在尝试将Honeypot实施为Wagtail电子邮件表单,但是我不了解如何将@check_honeypot装饰器添加到models.py中的类,该类会检查honeypot的有效性。
要设置Honeypot,需要将 @check_honeypot 装饰器添加到views.py中的表单视图中。不幸的是,w没有使用views.py,而是在models.py中构建了表单。
我如何在Wagtail表单上实现honeypot装饰器?
蜜罐仓库:https://github.com/jamesturk/django-honeypot Honeypot说明中的代码段:
要确保蜜罐字段同时存在且正确,您将需要使用honeypot.decorators中的check_honeypot装饰器:
从honeypot.decorators导入check_honeypot
@check_honeypot(field_name ='hp_field_name') def post_comment(要求): ... @check_honeypot def other_post_view(request): ...
解决方案:
@method_decorator(check_honeypot)
def render_landing_page
models.py
class FormField(AbstractFormField):
page = ParentalKey('FormPage', on_delete=models.CASCADE, related_name='form_fields')
class FormPage(AbstractEmailForm):
header = RichTextField(blank=True)
body = RichTextField(blank=True)
header_two = RichTextField(blank=True)
body_two = RichTextField(blank=True)
header_three = RichTextField(blank=True)
body_three = RichTextField(blank=True)
address = RichTextField(blank=True)
form_header = models.CharField(blank=True, max_length=100)
thank_you_text = RichTextField(blank=True)
content_panels = AbstractEmailForm.content_panels + [
FieldPanel('header', classname="full"),
FieldPanel('body', classname='full'),
FieldPanel('header_two', classname="full"),
FieldPanel('body_two', classname='full'),
FieldPanel('header_three', classname="full"),
FieldPanel('body_three', classname='full'),
FieldPanel('address', classname='full'),
FieldPanel('form_header', classname='full'),
InlinePanel('form_fields', label="Form fields"),
FieldPanel('thank_you_text', classname="full"),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('from_address', classname="col6"),
FieldPanel('to_address', classname="col6"),
]),
FieldPanel('subject'),
], "Email"),
]
thank_you_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
def render_landing_page(self, request, form_submission=None, *args, **kwargs):
if self.thank_you_page:
url = self.thank_you_page.url
# if a form_submission instance is available, append the id to URL
# when previewing landing page, there will not be a form_submission instance
if form_submission:
url += '?id=%s' % form_submission.id
return redirect(url, permanent=False)
# if no thank_you_page is set, render default landing page
return super().render_landing_page(request, form_submission, *args, **kwargs)
content_panels = AbstractEmailForm.content_panels + [
FieldPanel('header', classname="full"),
FieldPanel('body', classname='full'),
FieldPanel('header_two', classname="full"),
FieldPanel('body_two', classname='full'),
FieldPanel('header_three', classname="full"),
FieldPanel('body_three', classname='full'),
FieldPanel('address', classname='full'),
FieldPanel('form_header', classname='full'),
InlinePanel('form_fields'),
FieldPanel('thank_you_text', classname='full'),
PageChooserPanel('thank_you_page'),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('from_address', classname='col6'),
FieldPanel('to_address', classname='col6'),
]),
FieldPanel('subject'),
], 'Email'),
]
form.html
<section class="contact-background-lg" >
<div class="container px-0">
<div class="card p-m-5-0">
<form action="{% pageurl page %}" method="POST">
{% csrf_token %}
{% render_honeypot_field "phonenumber" %}
<div class="row">
<div class="col-md-12 col-sm-12">
{% if form.non_field_errors %}
<div class="alert alert-danger" role="alert">
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
<div class="card-title text-primary">
<h2><strong>{{ page.form_header }}</strong></h2><p class="pb-2 text-muted">Please complete the form below to receive a response within 24 hours.</p>
<hr>
<br>
</div>
</div>
{% for field in form.visible_fields %}
<div class="col-md-6 col-sm-12">
<div class="form-group pt-3">
{{ field.label_tag }}
{% render_field field class+="form-control" %}
</div>
</div>
{% endfor %}
</div>
<div class="pull-center">
<button type="submit" class="btn btn-primary-alt py-3 mt-3" style="width: 8rem;">Submit</button>
</div>
</form>
</div>
</div>
</section>