Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Django中,如何从模型/子级预填充编辑表单,但将提交保存为新实例?_Django_Django Models_Django Forms - Fatal编程技术网

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

在Django中,如何从模型/子级预填充编辑表单,但将提交保存为新实例?,django,django-models,django-forms,Django,Django Models,Django Forms,我试图用模型实例预填充ModelForm和inlineformset_工厂,但当用户提交表单时,我需要创建模型的新实例及其相关子记录 示例模型: class Artist(models.Model): artist = models.CharField(max_length=100) class Song(models.Model): artist = models.ForeignKey(Artist) song = models.CharField(max_lengt

我试图用模型实例预填充ModelForm和inlineformset_工厂,但当用户提交表单时,我需要创建模型的新实例及其相关子记录

示例模型:

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

class Song(models.Model):
    artist = models.ForeignKey(Artist)
    song = models.CharField(max_length=200)
我希望用户看到基于艺术家实例的编辑表单,以及该艺术家相关歌曲的InlineFormSet。表单将预先填充现有数据,用户可以更改艺术家的姓名和歌曲名称。但是,当用户提交表单时,我不想覆盖现有记录。相反,我想创建一个新的艺术家实例,并为这个新艺术家添加新歌曲

在保存之前,我尝试将“艺术家”的主键设置为“无”,这将强制创建一个新的“艺术家”实例。然而,我失去了艺术家和歌曲之间的异国情调

示例视图:

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})

我认为最简单的方法是设置默认值,将字典作为表单的第一个参数传入。可以通过以下方式获取模型实例的所有字段:

d_initial = Artist.objects.filter(pk=artist_id).values()[0]
这是你要传给表格的字典

form = ArtistEditForm(d_initial)

如果从表单中排除了任何内容,则可能需要将其从字典中删除。与
id
相同。但这将生成一个表单,该表单包含现有实例中的所有值,但将保存到新实例。

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

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()

我找到了这个片段,我想这更像是你在寻找的。
我遇到了一个类似的问题,我这样解决了它:

def edit(request, artist_id=None):
    if artist_id == None:
        artistsubmission = Artist()
    else:
        artistsubmission = get_object_or_404(Artist, id = artist_id)

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

        if form.is_valid() and formset.is_valid():
            artistsubmission.pk = None

            artist = form.save(commit=False)
            artist.id = None
            artist.save()

            for f in formset.forms:
                song = f.save(commit=False)
                song.artist_id = artist.id
                song.id = None
                song.save()
            return HttpResponseRedirect('/success/')
    else:
        form = ArtistEditForm(instance=artistsubmission)
        formset = SongFormSet(instance=artistsubmission)
    return render_to_response('edit.html', {'form':form, 'formset':formset})

谢谢-这对模型非常有效,但对inlineformset_工厂无效。似乎inlineformset\u工厂不会采用初始值。谢谢-我想我可以使用modelformset,但不能使用inlineformset。它需要我循环播放歌曲,设置初始值,然后对每个项目执行保存。这感觉就像我在重新创建许多inlineformset功能。如果我错过了一些东西,我将感谢任何额外的建议。谢谢;)我会将此标记为答案,并在完成此操作后发布一个关于InlineFormset的不同问题。再次感谢。但这意味着你的歌曲模型没有艺术家是有效的,这有点奇怪。。。