No Django, como posso pré-preencher um formulário de edição de um modelo / criança, mas salvar a apresentação como nova instância?

votos
4

Eu estou tentando preencher previamente um ModelForm e um inlineformset_factory com uma instância de um modelo, mas quando o usuário envia o formulário, eu preciso criar uma nova instância do modelo e ele está relacionado registros filho.

Exemplo Modelo:

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

class Song(models.Model):
    artist = models.ForeignKey(Artist)
    song = models.CharField(max_length=200)

Eu quero o usuário para ver um formulário de edição com base em uma instância do artista, juntamente com um InlineFormSet para músicas relacionadas desse artista. O formulário será preenchido com os dados existentes eo usuário pode alterar o nome do artista e os nomes das músicas. No entanto, quando o usuário envia o formulário, eu não deseja substituir os registros existentes. Em vez disso, eu quero criar uma nova instância do artista e adicionar novas músicas para este novo artista.

Tenho experimentado definindo a chave primária do artista para Nenhum antes de salvar - e isso força uma nova instância do artista. No entanto, eu perco a relação ForeignKey entre artistas e músicas.

Exemplo Ver:

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})
Publicado 26/04/2009 em 03:10
fonte usuário
Em outras línguas...                            


4 respostas

votos
4

Você pode iterar sobre as formas individuais em seu formset, altere o que você precisa e salvar.

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()
Respondeu 26/04/2009 em 07:24
fonte usuário

votos
2

Eu acho que a maneira mais fácil de fazer isso seria para definir valores padrão por meio de um dicionário em como o primeiro argumento para o formulário. Você pode obter todos os campos da instância de um modelo por

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

Este é o dicionário que você iria passar para o formulário.

form = ArtistEditForm(d_initial)

Se tiver excluído qualquer coisa, desde a forma, você pode querer removê-lo do dicionário. Mesmo para id. Mas isso deve produzir uma forma que tem todos os valores da instância existente, mas irá poupar para uma nova instância.

Respondeu 26/04/2009 em 06:55
fonte usuário

votos
1

Eu tive um problema semelhante e eu resolvi-lo assim:

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})
Respondeu 14/07/2009 em 11:23
fonte usuário

votos
0

Eu encontrei este trecho que eu acho que foi mais o que você estava procurando. http://www.djangosnippets.org/snippets/1246/

Respondeu 27/06/2009 em 22:04
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more