在 Django 中,如何从模型/子项预填充编辑表单,但将提交保存为新实例?

6 django django-models django-forms

我正在尝试使用模型的实例预填充 ModelForm 和 inlineformset_factory ,但是当用户提交表单时,我需要创建模型的新实例及其相关的子记录。

型号示例:

class Artist(models.Model):
    artist = models.CharField(max_length=100)

class Song(models.Model):
    artist = models.ForeignKey(Artist)
    song = models.CharField(max_length=200)
Run Code Online (Sandbox Code Playgroud)

我希望用户看到基于艺术家实例的编辑表单,以及该艺术家相关歌曲的 InlineFormSet。该表格将预先填充现有数据,用户可以更改艺术家的姓名和歌曲名称。但是,当用户提交表单时,我不想覆盖现有记录。相反,我想创建一个新的艺术家实例并为这位新艺术家添加新歌曲。

我尝试在保存之前将艺术家的主键设置为 None - 这会强制创建一个新的 Artist 实例。但是,我失去了艺术家和歌曲之间的外键关系。

视图示例:

def edit(request, artist_id=None):
    if  artist_id == None:
        artistsubmission = Artist()
    else:
        artistsubmission = Artist.objects.get(id = artist_id)
        artistsubmission.pk = None

    if request.method == 'POST':
        form = ArtistEditForm(request.POST, instance=artistsubmission)
        formset = SongFormSet(request.POST, instance=artistsubmission)

        if form.is_valid() and formset.is_valid():
            form.save()
            formset.save()
            return HttpResponseRedirect('/success/')    
    else:
        form = ArtistEditForm(instance=artistsubmission)
        formset = SongFormSet(instance=artistsubmission)

    return render_to_response('edit.html', {'form':form, 'formset':formset})
Run Code Online (Sandbox Code Playgroud)

Har*_*old 5

您可以迭代表单集中的各个表单,更改您需要的内容并保存。

if form.is_valid() and formset.is_valid():
    artist = form.save()
    for f in formset.forms:
        song = f.save(commit=False)
        song.artist = artist.id
        song.save()
Run Code Online (Sandbox Code Playgroud)