在Django表单中移除带复选框的项目

2 投票
2 回答
1102 浏览
提问于 2025-04-16 01:32

我正在用Django写一个表单。这个表单是针对一个叫做Experiment的模型的模型表单。每个Experiment都有几个关联的TimeSlot模型,这些模型是通过ForeignKey('Experiment')来连接的。我想在EditExperimentForm中添加一个选项,可以通过勾选框来删除一个或多个TimeSlot实例。

目前,我在EditExperimentForminit函数中通过循环来定义所有的复选框:

def __init__(self, *args, **kwargs):
    super(EditExperimentForm,self).__init__(*args,**kwargs)
    experiment = self.instance
    for timeslot in experiment.timeslot_set.all():
        self.fields['timeslot-'+str(timeslot.id)] = BooleanField(label="Remove Timeslot at "+str(timeslot.start),required=False)

然后在提交时,我使用正则表达式来处理这些复选框:

timeslot_re = re.compile(r'^timeslot-([\d]+)$')
            for key in form.data.keys():
            match = timeslot_re.match(key)
            if match:
                timeslot = TimeSlot.objects.get(id=match.expand(r'\1'))
                timeslot.delete()

这种方法远不是优雅的解决方案(其中一个问题是,这让任何不太通用的模板变得非常麻烦。有没有人能想到更简单的方法来实现这个?

2 个回答

1

如果你用模型表单集来处理你的时间段对象,可能会更简洁一些。你有没有考虑过这个方法呢?

http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#id1

1

这段代码没有经过测试,但类似这样的代码应该可以实现你的需求:

class MyForm(forms.Form):
    # You can change the queryset in the __init__ method, but this should be a nice basis
    timeslots = forms.ModelMultipleChoiceFieldqueryset=Timeslot.objects.all(), widget=forms.CheckboxSelectMultiple)

    def save(self):
        # make sure you do a form.is_valid() before trying to save()
        for timeslot in self.cleaned_data['timeslots']:
            timeslot.delete()

撰写回答