将标签添加到w电子邮件表单提交中

问题描述

为了能够自动使用the式电子邮件表单发送的电子邮件,我需要在生成的行之前放置一些标签。 简而言之,电子邮件中的一行应如下所示:“#Start#descr:something。#Ende#”。 我设法向the“表单创建者”添加了一个“ start_tag”和一个“ end_tag”字段,但是现在尝试提交表单时出现错误。

管理表单编辑器:

Take a look at my admin form editor.

更新 新错误:

    NameError at /anforderungsformular/
name 'start_tag' is not defined
Request Method: POST
Request URL:    http://localhost:8000/anforderungsformular/
Django Version: 3.0.8
Exception Type: NameError
Exception Value:    
name 'start_tag' is not defined
Exception Location: C:\Program Files (x86)\Python38-32\lib\site-packages\wagtail\contrib\forms\models.py in send_mail,line 293
Python Executable:  C:\Program Files (x86)\Python38-32\python.exe
Python Version: 3.8.3
Python Path:    
['U:\\IT\\itseite_design','C:\\Program Files (x86)\\Python38-32\\python38.zip','C:\\Program Files (x86)\\Python38-32\\DLLs','C:\\Program Files (x86)\\Python38-32\\lib','C:\\Program Files (x86)\\Python38-32','C:\\Users\\priwitzl\\AppData\\Roaming\\Python\\Python38\\site-packages','C:\\Program Files (x86)\\Python38-32\\lib\\site-packages']
Server time:    Di,11 Aug 2020 12:32:38 +0000

我更改了wagtail/contrib/forms/models.py(基本上我将start_tagend_tag添加为charFields,并将它们添加到面板中。

import json
import os

from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
from django.template.response import TemplateResponse
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from unidecode import unidecode

from wagtail.admin.edit_handlers import FieldPanel
from wagtail.admin.mail import send_mail
from wagtail.core.models import Orderable,Page

from .forms import FormBuilder,WagtailAdminFormPageForm


FORM_FIELD_CHOICES = (
    ('singleline',_('Single line text')),('multiline',_('Multi-line text')),('email',_('Email')),('number',_('Number')),('url',_('URL')),('checkbox',_('Checkbox')),('checkboxes',_('Checkboxes')),('dropdown',_('Drop down')),('multiselect',_('Multiple select')),('radio',_('Radio buttons')),('date',_('Date')),('datetime',_('Date/time')),('hidden',_('Hidden field')),)


class AbstractFormSubmission(models.Model):
    """
    Data for a form submission.

    You can create custom submission model based on this abstract model.
    For example,if you need to save additional data or a reference to a user.
    """

    form_data = models.TextField()
    page = models.ForeignKey(Page,on_delete=models.CASCADE)

    submit_time = models.DateTimeField(verbose_name=_('submit time'),auto_now_add=True)

    def get_data(self):
        """
        Returns dict with form data.

        You can override this method to add additional data.
        """
        form_data = json.loads(self.form_data)
        form_data.update({
            'submit_time': self.submit_time,})

        return form_data

    def __str__(self):
        return self.form_data

    class Meta:
        abstract = True
        verbose_name = _('form submission')
        verbose_name_plural = _('form submissions')


class FormSubmission(AbstractFormSubmission):
    """Data for a Form submission."""


class AbstractFormField(Orderable):
    """
    Database Fields required for building a Django Form field.
    """
    label = models.CharField(
        verbose_name=_('label'),max_length=255,help_text=_('The label of the form field')
    )
    field_type = models.CharField(verbose_name=_('field type'),max_length=16,choices=FORM_FIELD_CHOICES)
    required = models.BooleanField(verbose_name=_('required'),default=True)
    choices = models.TextField(
        verbose_name=_('choices'),blank=True,help_text=_('Comma separated list of choices. Only applicable in checkboxes,radio and dropdown.')
    )
    default_value = models.CharField(
        verbose_name=_('default value'),help_text=_('Default value. Comma separated values supported for checkboxes.')
    )
    help_text = models.CharField(verbose_name=_('help text'),blank=True)
    start_tag = models.CharField(verbose_name=_('start_tag'),blank=True)
    end_tag = models.CharField(verbose_name =_('end_tag'),blank=True)

    @property
    def clean_name(self):
        # unidecode will return an ascii string while slugify wants a
        # unicode string on the other hand,slugify returns a safe-string
        # which will be converted to a normal str
        return str(slugify(str(unidecode(self.label))))

    panels = [
        FieldPanel('label'),FieldPanel('help_text'),FieldPanel('required'),FieldPanel('field_type',classname="formbuilder-type"),FieldPanel('choices',classname="formbuilder-choices"),FieldPanel('default_value',classname="formbuilder-default"),FieldPanel('start_tag'),FieldPanel('end_tag'),]

    class Meta:
        abstract = True
        ordering = ['sort_order']


class AbstractForm(Page):
    """
    A Form Page. Pages implementing a form should inherit from it
    """

    base_form_class = WagtailAdminFormPageForm

    form_builder = FormBuilder

    submissions_list_view_class = None

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        if not hasattr(self,'landing_page_template'):
            name,ext = os.path.splitext(self.template)
            self.landing_page_template = name + '_landing' + ext

    class Meta:
        abstract = True

    def get_form_fields(self):
        """
        Form page expects `form_fields` to be declared.
        If you want to change backwards relation name,you need to override this method.
        """

        return self.form_fields.all()

    def get_data_fields(self):
        """
        Returns a list of tuples with (field_name,field_label).
        """

        data_fields = [
            ('submit_time',_('Submission date')),]
        data_fields += [
            (field.clean_name,field.label)
            for field in self.get_form_fields()
        ]

        return data_fields

    def get_form_class(self):
        fb = self.form_builder(self.get_form_fields())
        return fb.get_form_class()

    def get_form_parameters(self):
        return {}

    def get_form(self,**kwargs):
        form_class = self.get_form_class()
        form_params = self.get_form_parameters()
        form_params.update(kwargs)

        return form_class(*args,**form_params)

    def get_landing_page_template(self,request,**kwargs):
        return self.landing_page_template

    def get_submission_class(self):
        """
        Returns submission class.

        You can override this method to provide custom submission class.
        Your class must be inherited from AbstractFormSubmission.
        """

        return FormSubmission

    def get_submissions_list_view_class(self):
        from .views import SubmissionsListView
        return self.submissions_list_view_class or SubmissionsListView

    def process_form_submission(self,form):
        """
        Accepts form instance with submitted data,user and page.
        Creates submission instance.

        You can override this method if you want to have custom creation logic.
        For example,if you want to save reference to a user.
        """

        return self.get_submission_class().objects.create(
            form_data=json.dumps(form.cleaned_data,cls=DjangoJSONEncoder),page=self,)

    def render_landing_page(self,form_submission=None,**kwargs):
        """
        Renders the landing page.

        You can override this method to return a different HttpResponse as
        landing page. E.g. you could return a redirect to a separate page.
        """
        context = self.get_context(request)
        context['form_submission'] = form_submission
        return TemplateResponse(
            request,self.get_landing_page_template(request),context
        )

    def serve_submissions_list_view(self,**kwargs):
        """
        Returns list submissions view for admin.

        `list_submissions_view_class` can bse set to provide custom view class.
        Your class must be inherited from SubmissionsListView.
        """
        view = self.get_submissions_list_view_class().as_view()
        return view(request,form_page=self,**kwargs)

    def serve(self,**kwargs):
        if request.method == 'POST':
            form = self.get_form(request.POST,request.FILES,user=request.user)

            if form.is_valid():
                form_submission = self.process_form_submission(form)
                return self.render_landing_page(request,form_submission,**kwargs)
        else:
            form = self.get_form(page=self,user=request.user)

        context = self.get_context(request)
        context['form'] = form
        return TemplateResponse(
            request,self.get_template(request),context
        )

    preview_modes = [
        ('form',_('Form')),('landing',_('Landing page')),]

    def serve_preview(self,mode):
        if mode == 'landing':
            request.is_preview = True
            return self.render_landing_page(request)
        else:
            return super().serve_preview(request,mode)


class AbstractEmailForm(AbstractForm):
    """
    A Form Page that sends email. Pages implementing a form to be send to an email should inherit from it
    """

    to_address = models.CharField(
        verbose_name=_('to address'),help_text=_("Optional - form submissions will be emailed to these addresses. Separate multiple addresses by comma.")
    )
    from_address = models.CharField(verbose_name=_('from address'),blank=True)
    subject = models.CharField(verbose_name=_('subject'),blank=True)

    def process_form_submission(self,form):
        submission = super().process_form_submission(form)
        if self.to_address:
            self.send_mail(form)
        return submission

    def send_mail(self,form):
        addresses = [x.strip() for x in self.to_address.split(',')]
        content = []
        for field in form:
            value = field.value()
            if isinstance(value,list):
                value = ','.join(value)
            content.append('{}: {}'.format(start_tag,field.label,value,end_tag))
        content = '\n'.join(content)
        send_mail(self.subject,content,addresses,self.from_address,)

    class Meta:
        abstract = True

我想尝试发送邮件时会出现问题。 表单网站加载完毕,我可以填写任何字段。但是当我尝试提交时,我得到了错误。

content.append('{}: {}'.format(start_tag,end_tag))

我的猜测是我以错误的方式调用了变量,但我想不出正确的方法。

我希望我能很好地解释我的问题。我很高兴能得到任何帮助。

解决方法

如我所见。 第一个问题是在 content.append('{}: {}'.format(start_tag,field.label,value,end_tag)) 仅提供了两个弯括号而得到了4个参数,此外,您没有导入((start_tag))或((end_tag)),因为您在不同的模型中定义了它们(作为字段),但您在将它们与 field.label value 组合在一起的不同模型中调用了它们, 提示:如果仍然出现错误,则可能应该检查tyopos(写错误)

,

为此

(依此类推。下面是我想知道的棘手部分:我想在生成电子邮件时使用“ start_tag”和“ end_tag”。因此, 这:“标签”:“值”换行符“标签”:“值” ...,我想做 这:“ start_tag”“标签”:“值”“ end_tag”换行 “ start_tag”“ label”:“ value”“ end_tag” ...由于我的问题在 系统尝试发送电子邮件,我知道我调用了变量 “ start / end_tag”的输入方式有误。如您所说,我尝试调用一个变量 一个不同的模块。我很困惑,因为变量“ field.label”可以 被调用,而不是“ field.start_tag”等。希望对您有帮助)

(我认为)最好的方法是创建装饰器,并将最新的字典包装到其中。

对于您的信息:电子邮件发送过程与您的需求无关。.

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...