Django:使用自定义多对多模型保存ModelForm

3 投票
2 回答
1821 浏览
提问于 2025-04-16 06:07

我有一些Publication(出版物)和Author(作者)。因为作者的顺序很重要(教授不想被排在贡献了一些微不足道数据的实习生后面),所以我定义了一个自定义的多对多模型:

class Authorship(models.Model):
    author = models.ForeignKey("Author")
    publication = models.ForeignKey("Publication")
    ordering = models.IntegerField(default=0)

class Author(models.Model):
    name = models.CharField(max_length=100)

class Publication(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author, through=Authorship)

我为出版物创建了一个ModelForm,并在一个视图中使用它。问题是,当我调用form.save()时,作者显然是按照默认的顺序(也就是0)被添加的。我写了一个OrderedModelMultipleChoiceField,里面有一个clean方法,可以返回按正确顺序保存的对象,但我找不到一个地方可以真正保存多对多的数据,这样我就可以自己添加、编辑或删除Authorship实例。

有什么想法吗?

2 个回答

1

我不太确定有没有现成的解决办法,但你可以手动保存数据,像这样:

form = PublicationForm(...)
pub = form.save(commit=False)
pub.save()
form.save_m2m()

这样你就可以根据需要在中间处理任何自定义的操作。可以查看文档中的例子,了解一下保存方法

2

如果你在使用一个自定义的多对多(M2M)表,并且用了 through 参数,那么我觉得你需要手动保存数据,才能保存那些额外的字段。所以在你的视图里,你需要添加:

...
publication = form.save()
#assuming that these records are in order! They may not be
order_idx = 0
for author in request.POST.getlist('authors'): 
    authorship = Authorship(author=author, publication=publication, ordering=order_idx)
    authorship.save()
    order_idx += 1

你也可以把这个放在你的模型表单(ModelForm)的 save 函数里。

撰写回答