Wagtail Form Builder 文档指出:
form_page.html 与标准 Wagtail 模板的不同之处在于它是 还传递了一个变量
,其中包含 Django Form 对象 到通常的form
变量。page
但在我当前的项目中,我需要在另一个页面中嵌入一个联系表单(作为表单生成器页面实现)。在该目标页面的模型中,我使用 PageChooserPanel 让编辑器选择要嵌入的表单页面。换句话说:
class TargetPage(Page):
[...snip...]
contact_form = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
content_panels = Page.content_panels + [
[...snip...]
PageChooserPanel('contact_form', 'FormPage'),
]
我的问题出在目标页面的模板中。我可以通过
page.contact_form
访问表单页面的属性,但由于该页面没有传入 form
对象,所以我不知道如何渲染我的字段。
我猜测我需要重写目标页面的 get_context() ,以便它包含我需要的
form
对象。但我不知道如何获得该对象。有好心人能让我走上正轨吗?
经过一夜的睡眠,答案变得比较明显了。缺少的链接是 Wagtail FormPage 的 get_form() 方法。我现在在我的 TargetPage 模型中使用它:
def attached_form(self):
return self.contact_form.specific.get_form()
因此,在我的模板中,我可以参考attached_form来获取我的字段。
#home/models.py
class HomePage(Page):
subscription_form = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+',
)
content_panels = Page.content_panels + [
PageChooserPanel('subscription_form', 'home.FormPage'),
]
def attached_form(self):
return self.subscription_form.specific.get_form()
def attached_form_url(self):
return self.subscription_form.get_url();
.... #home/models.py
class FormField(AbstractFormField):
page = ParentalKey(
"FormPage", related_name="form_fields", on_delete=models.CASCADE)
... #home/models.py
class FormPage(AbstractEmailForm):
image = models.ForeignKey(
"wagtailimages.Image",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="+",
)
body = StreamField(BaseStreamBlock(), use_json_field=True)
thank_you_text = RichTextField(blank=True)
# Note how we include the FormField object via an InlinePanel using the
# related_name value
content_panels = AbstractEmailForm.content_panels + [
FieldPanel("image"),
FieldPanel("body"),
InlinePanel("form_fields", heading="Form fields", label="Field"),
FieldPanel("thank_you_text"),
MultiFieldPanel(
[
FieldRowPanel(
[
FieldPanel("from_address"),
FieldPanel("to_address"),
]
),
FieldPanel("subject"),
],
"Email",
),
]
在“home/templates/home/home_page.html
我正在使用顺风CSS。
<style>
input, textarea {
width: 100%;
background: rgb(209 213 219 / var(--tw-bg-opacity));
border-radius: 6px;
padding: 0.75rem;
}
</style>
<form class="pt-16 form" action="{{ page.attached_form_url }}" method="POST">
{% csrf_token %}
{% for field in page.attached_form %}
<div class="pt-10 grid grid-cols-1 md:grid-cols-5 px-4">
<div> </div>
<div class="col-span-3 w-full">
<div class="container flex flex-col xl:flex-row mx-auto px-5 py-8 xl:py-14 text-gray-500 bg-gray-200 rounded-2xl">
<div class="w-full mb-6 xl:mb-0 sm:text-center">
<div class="mb-4 text-gray-900 text-3xl font-extrabold">Join 2,000+ subscribers</div>
<div class="text-lg">Stay in the loop with everything you need to know.</div>
</div>
<div class="w-full">
<div class="flex flex-col justify-center sm:flex-row gap-3 w-full">
{{ field }}
<button type="submit" class="sm:w-1/4 h-12 text-white bg-purple-600 rounded-lg shadow transition-all duration-300 ease-in-out hover:bg-purple-700">Subscribe</button>
</div>
<div class="mt-3 text-sm sm:text-center">We care about your data in our <u class="cursor-pointer transition-all duration-300 ease-in-out hover:text-gray-700">privacy policy</u>.</div>
</div>
</div>
</div>
<div> </div>
</div>
</form>
我也有
home/templates/home/form_page_landing.html 和 home/templates/home/form_page.html
两个模板文件。当用户通过电子邮件地址“订阅”时,会使用“home/templates/home/form_page_landing.html”,用户将被重定向到“home/templates/home/form_page_landing.html”页面。