如何保存带有ModelMultipleChoiceField的表单?

2 投票
1 回答
2299 浏览
提问于 2025-04-15 16:36

我有一个叫做日历的模型,在一个表单里我想能够创建多个这个模型的实例。

以下是我的模型:

class Event(models.Model):
    user = models.ForeignKey(User)

class Group(models.Model):
    name = models.CharField(_('Name'), max_length=80)
    events = models.ManyToManyField(Event, through='Calendar')

class Calendar(models.Model):
    event = models.ForeignKey(Event)
    group = models.ForeignKey(Group)

class CalendarInline(admin.TabularInline):
    model = Calendar
    extra = 1

class GroupAdmin(admin.ModelAdmin):
    inlines = (CalendarInline,)

这是我尝试编写表单的代码:

class AddEventToGroupForm(ModelForm):
    group = ModelMultipleChoiceField(queryset=Group.objects.all(), widget=SelectMultiple())

    def save(self):
        for g in self:
            g.save()

    class Meta:
        model = Calendar
        fields = ('group',)

这是我视图的一部分:

e = Event.objects.get(id=event_id)
calentry = Calendar(event=e)
if request.POST:
    f = AddEventToGroupForm(data=request.POST, instance=calentry)
    if f.is_valid():
        f.save()

如果我尝试提交这个表单,我会得到:

AttributeError at /groups/add_event/7/

'BoundField' object has no attribute 'save'

在这种情况下,正确的方法是什么,才能创建多个日历的实例呢?

1 个回答

2

处理表单中的多对多关系不是这样做的。你不能简单地遍历表单中的字段并保存它们,这样是行不通的。

在这个表单中,只有一个字段,但它有多个值。正确的做法是遍历这个字段的,这些值可以在cleaned_data字典中找到(当表单有效时)。

所以,在你的视图中,你可以这样做:

if f.is_valid():
    for group in f.cleaned_data['group']:
        calentry.groups.add(group)

注意,你并没有真正“保存”AddEventToGroupForm这个表单。我建议把它做成一个标准的forms.Form,而不是ModelForm,因为你并不依赖ModelForm的任何功能。

撰写回答