我正在编写一个新的网页,该网页也应作为某些事件的注册平台。我想在多选字段的options['prices']
边添加options['choices']
。
现在有一个供选择的字段,其中choiceas用逗号分隔,我希望另一个字段根据选择(浮动,尽管可以在其他地方进行处理)输入默认值与默认值的差价,例如"1, 2.5, -1, 0"
。表格末尾应计算默认值和所有可能的选择之和。
我尝试修改wagtail.contrib.contrib.forms.FormBuilder.create_multiselect_field
失败。有没有办法添加这种功能,基本上只是一个附加的选项输入?
答案 0 :(得分:1)
最后找到了一种方法,并再次学到了很多东西。
是的,这是可能的,甚至是相当简单的方法。我的表单使用的是AbstractEmailForm,我不得不重写以下方法和变量:
MyForm类(AbstractEmailForm):
form_builder = CustomFormBuilder
def get_submission_class(self):
return CustomFormSubmission
def process_form_submission(self, form):
#This function processed input data form.cleaned_data dict when user is submitting the form
#Fields are defined in CustomFormSubmission
total_price = self.default_price
form_fields = self.get_form_fields()
for i in form_fields:
if i.prices: #if form creator has defined varying prices for choices
#creates dict {key=choice, value=price} for every form field
price_dict = dict(zip(
[x.strip() for x in i.choices.split(',')],
[Decimal(x.strip()) for x in i.prices.split(',')], #field type is DecimalField, float is not applicable
))
total_price += price_dict[form.cleaned_data[i.label.lower()]]
return self.get_submission_class().objects.create(
form_data=json.dumps(form.cleaned_data, cls=DjangoJSONEncoder),
page=self,
price=total_price,
)
def get_data_fields(self):
"""
Returns a list of tuples with (field_name, field_label).
"""
data_fields = [
('submit_time', _('Submission date')),
('price', _('Total Price')),
]
data_fields += [
(field.clean_name, field.label)
for field in self.get_form_fields()
]
return data_fields
此外,我还必须为表单编辑器字段选择价格。这可以通过重写AbstractFormField类来实现。您必须在要应用价格选项的地方覆盖每个create__field()函数。例如下面的create_radio_field:
FormField(AbstractFormField)类:
prices = models.TextField(
verbose_name=_('prices'),
blank=True,
help_text=_('Comma separated list of price changes.')
)
panels = [
FieldPanel('label'),
FieldPanel('help_text'),
FieldPanel('required'),
FieldPanel('field_type', classname="formbuilder-type"),
FieldPanel('choices', classname="formbuilder-choices"),
FieldPanel('prices'),
FieldPanel('default_value', classname="formbuilder-default"),
]
def create_radio_field(self, field, options):
options['choices'] = [(x.strip(), x.strip()) for x in field.choices.split(',')]
options['prices'] = [x.strip() for x in field.prices.split(',')]
return django.forms.ChoiceField(
widget=django.forms.RadioSelect,
**options
)
enter code here
#remember to create CustomFormBuilder(FormBuilder) if you have custom fields, ex. Generic IP-address:
class CustomFormBuilder(FormBuilder):
def create_ipaddress_field(self, field, options):
return forms.GenericIPAddressField(
**options
)
要保存此值,请使用CustomFormSubmission(AbstractFormSubmission)定义要在数据库中创建的字段
price = models.DecimalField(
max_digits=16,
decimal_places=2,
default=0,
)
def get_data(self):
"""
Returns dict with form data.
"""
form_data = json.loads(self.form_data)
form_data.update({
'submit_time': self.submit_time,
'price': self.price,
})
return form_data
货币保存在Django模型中。DecimalField仅需要2个小数。浮点数在取整时可能会有奇怪的行为。
如果您有任何疑问,我将很乐意为您打开更多代码!