我正在尝试在Django 1.11中构建一个表单,其中在监视列表上有一组复选框,以允许用户在要稍后接收通知的项目上设置多个警报。但是,我不确定如何在这样的字段上表示多个选项。
这是我的模型代码:
class Watchlist(models.Model):
CLOSES_IN_2_WEEKS, CLOSES_IN_1_WEEKS, CLOSES_IN_3_DAYS, CLOSES_TOMORROW = (
"CLOSES_IN_2_WEEKS",
"CLOSES_IN_1_WEEKS",
"CLOSES_IN_3_DAYS",
"CLOSES_TOMORROW"
)
ALERT_OPTIONS = (
(CLOSES_IN_2_WEEKS, "Closes in 2 weeks",),
(CLOSES_IN_1_WEEKS, "Closes in 1 weeks",),
(CLOSES_IN_3_DAYS, "Closes in 3 days",),
(CLOSES_TOMORROW, "Closes tomorrow",),
)
# I want to store more than one option
alert_options = models.CharField(max_length=255, blank=True)
def save(self):
"""
If this is submitted create 1 alert:
"CLOSES_IN_1_WEEKS"
If this submitted, create 3 alerts:
"CLOSES_IN_2_WEEKS",
"CLOSES_IN_1_WEEKS",
"CLOSES_IN_3_DAYS",
"""
# split the submitted text values, to create them
# yes, this should probably be a formset. I wasn't sure how I'd
# handle the logic of showing 4 optional alerts, and only creating models
# on the form submission, and remembering to delete them when a user
# unchecked the choices in the form below
下面是我正在使用的表格。我迷上了__init__
方法,以用可能的选择预先填充表格。
class WatchlistForm(forms.ModelForm):
alert_options = forms.ChoiceField(
choices=[],
label="Alert Options",
required=False,
widget=forms.CheckboxSelectMultiple(),
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["alert_options"].choices = WatchlistForm.ALERT_OPTIONS
def clean_alert_options(self):
# I'm dropping into ipython to look around here
import ipdb; ipdb.set_trace()
return data["alert_options"]
class Meta:
model = WatchlistForm
fields = ("alert_options")
目前,此功能对于单个选中的复选框可以正常使用,但是一旦我有多个复选框,则只能选择最后一个选项,而且我不知道该如何使用它。
我如何 在这里捕获所有的选择,而不仅仅是一个?
我知道我可能应该在这里使用表单集。事实是,对我来说,如何创建一组预填充的表单集选项来表示一些活动和不活动的警报选择并不清楚。
使用测试显示我要做什么如果有帮助,我正在尝试保存信息,以便将其存储为-我在测试套件中使用pytest添加了一些基于我的伪代码。
def test_form_accepts_multiple_alert_values(self, db, verified_user):
form_data = {
"user_id": verified_user.id,
"alert_options": "CLOSES_IN_2_WEEKS CLOSES_IN_3_DAYS",
}
submission = forms.WatchlistForm(form_data)
instance = submission.save()
assert instance.alert_options == "CLOSES_IN_2_WEEKS CLOSES_IN_3_DAYS",