Files
wagtailcms/apps/forms/models.py
T
Zhengen 12f7caa158 feat: add products/cases page models and forms lead-capture app
- apps/products: ProductIndexPage/ProductPage
- apps/cases: CaseStudyIndexPage/CaseStudyPage
- apps/forms: FormDefinition/FormDefinitionField/Lead + submit API
- core/blocks: CaseStudyBlock, FormBlock (with API representation)
- register new apps, custom leads API route, migrations
2026-08-06 16:04:21 +08:00

114 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
线索表单:FormDefinition 是可复用的表单定义 Snippet,通过 core.blocks.FormBlock
嵌入任意 StreamField 页面;提交结果保存为 Lead。
详见 documents/设计方案分析与完善版.md §2.6FormBlock)与 B2B 官网核心转化路径。
"""
from django.db import models
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.admin.panels import FieldPanel, InlinePanel
from wagtail.models import Orderable
from wagtail.snippets.models import register_snippet
FIELD_TYPE_CHOICES = [
("text", "单行文本"),
("textarea", "多行文本"),
("email", "邮箱"),
("tel", "电话"),
("select", "下拉选择"),
]
@register_snippet
class FormDefinition(ClusterableModel):
"""可复用的线索表单定义。"""
name = models.CharField(max_length=100, verbose_name="表单名称")
submit_button_text = models.CharField(
max_length=50, default="提交", verbose_name="提交按钮文案"
)
success_message = models.CharField(
max_length=200,
default="提交成功,我们会尽快与您联系。",
verbose_name="提交成功提示",
)
notification_email = models.EmailField(blank=True, verbose_name="通知邮箱")
panels = [
FieldPanel("name"),
FieldPanel("submit_button_text"),
FieldPanel("success_message"),
FieldPanel("notification_email"),
InlinePanel("fields", label="表单字段"),
]
class Meta:
verbose_name = "线索表单"
verbose_name_plural = "线索表单"
def __str__(self):
return self.name
class FormDefinitionField(Orderable):
"""FormDefinition 的子字段,编辑器在后台可自由增删排序。"""
form = ParentalKey(
FormDefinition, on_delete=models.CASCADE, related_name="fields"
)
label = models.CharField(max_length=100, verbose_name="字段标签")
field_key = models.SlugField(
max_length=50,
verbose_name="字段标识",
help_text="提交数据中使用的 key,例如 name / email / phone",
)
field_type = models.CharField(
max_length=20, choices=FIELD_TYPE_CHOICES, default="text", verbose_name="字段类型"
)
required = models.BooleanField(default=True, verbose_name="是否必填")
choices = models.CharField(
max_length=255,
blank=True,
verbose_name="可选项",
help_text="逗号分隔,仅“下拉选择”类型使用",
)
panels = [
FieldPanel("label"),
FieldPanel("field_key"),
FieldPanel("field_type"),
FieldPanel("required"),
FieldPanel("choices"),
]
@register_snippet
class Lead(models.Model):
"""表单提交产生的线索记录,供销售/市场团队在后台查看。"""
form = models.ForeignKey(
FormDefinition,
on_delete=models.SET_NULL,
null=True,
related_name="leads",
verbose_name="来源表单",
)
data = models.JSONField(default=dict, verbose_name="提交数据")
source_url = models.URLField(blank=True, verbose_name="来源页面")
created_at = models.DateTimeField(auto_now_add=True, verbose_name="提交时间")
panels = [
FieldPanel("form"),
FieldPanel("data"),
FieldPanel("source_url"),
]
class Meta:
verbose_name = "线索"
verbose_name_plural = "线索"
ordering = ["-created_at"]
def __str__(self):
form_name = self.form.name if self.form_id else "(表单已删除)"
return f"{form_name} - {self.created_at:%Y-%m-%d %H:%M}"