4

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)

ユーザーに、Artist のインスタンスに基づく編集フォームと、その Artist の関連する曲の InlineFormSet を表示してもらいたいと考えています。フォームには既存のデータが事前入力され、ユーザーはアーティスト名と曲名を変更できます。ただし、ユーザーがフォームを送信するときに、既存のレコードを上書きしたくありません。代わりに、Artist の新しいインスタンスを作成し、この新しいアーティストの新しい曲を追加したいと考えています。

保存する前に、artist の主キーを None に設定しようとしました。これにより、Artist の新しいインスタンスが強制的に作成されます。ただし、アーティストと曲の間の ForeignKey 関係を失います。

例のビュー:

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

4 に答える 4

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()
于 2009-04-26T06:24:36.440 に答える
2

これを行う最も簡単な方法は、フォームの最初の引数として辞書を渡すことによってデフォルト値を設定することだと思います。モデルインスタンスのすべてのフィールドは、次の方法で取得できます。

d_initial = Artist.objects.filter(pk=artist_id).values()[0]

これは、フォームに渡す辞書です。

form = ArtistEditForm(d_initial)

フォームから何かを除外した場合は、辞書から削除することをお勧めします。についても同じですid。ただし、これにより、既存のインスタンスのすべての値を持つフォームが生成されますが、新しいインスタンスに保存されます。

于 2009-04-26T05:55:28.053 に答える
1

同様の問題があり、次のように解決しました。

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})
于 2009-07-14T10:23:06.387 に答える
0

私はあなたが探していたものだと思うこのスニペットを見つけました。 http://www.djangosnippets.org/snippets/1246/

于 2009-06-27T21:04:25.993 に答える