В Django, как я могу предварительно заполнить форму редактирования из модели / потомка, но сохранить отправку как новый экземпляр? - PullRequest
4 голосов
/ 26 апреля 2009

Я пытаюсь предварительно заполнить ModelForm и inlineformset_factory экземпляром Model, НО, когда пользователь отправляет форму, мне нужно создать новый экземпляр Model и связанные дочерние записи.

Пример модели:

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, вместе с InlineFormSet для композиций, связанных с этим Artist. Форма будет предварительно заполнена существующими данными, и пользователь сможет изменить имя исполнителя и названия песен. Однако, когда пользователь отправляет форму, я не хочу перезаписывать существующие записи. Вместо этого я хочу создать новый экземпляр 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 голосов
/ 26 апреля 2009

Вы можете перебирать отдельные формы в вашем наборе форм, изменять то, что вам нужно, и сохранять.

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()
2 голосов
/ 26 апреля 2009

Я думаю, что самый простой способ сделать это - установить значения по умолчанию, передав словарь в качестве первого аргумента формы. Вы можете получить все поля экземпляра модели:

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

Это словарь, который вы передадите в форму.

form = ArtistEditForm(d_initial)

Если вы исключили что-либо из формы, вы можете удалить это из словаря. То же самое для id. Но это должно привести к форме, которая имеет все значения из существующего экземпляра, но сохранит в новый экземпляр.

1 голос
/ 14 июля 2009

У меня была похожая проблема, и я решил ее так:

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})
0 голосов
/ 28 июня 2009

Я нашел этот фрагмент, который, я думаю, был больше, чем вы искали. http://www.djangosnippets.org/snippets/1246/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...