Pangolin
Pangolin

Reputation: 31

Django passing Foreign Keys with multiple forms on a page

I am fairly new to Django and struggling a bit on how to get the primary keys from form input on a multiform view. I cannot get the keys into the database.

I have 3 models: Human, Human_notes, and Location. My form is made of these separate models as forms on one view. I thought I should collect the primary key from each form once saved and apply that to the next form data as a foreign key...

        <form action="human-add" method="POST">
            {% csrf_token %}
            {{ human_form.as_p }}
            {{ location_form.as_p }}
            {{ human_notes_form.as_p }}
            <button type="submit" class="save btn btn-success">Save</button>
        </form>

Human has FKs to Location...:

class Human(models.Model):
    intaker = models.ForeignKey(User, default=None, on_delete=models.SET_NULL, null=True)
    location = models.OneToOneField('Location', on_delete=models.SET_NULL, null=True,   related_name='humans')

Human_notes has FK to Human...(maybe this will become an FK in Human but originally thought many notes for one human) :

class HumanNotes(models.Model):
    human = models.ForeignKey(Human, on_delete=models.SET_NULL, null=True, related_name='humans_notes')

My view is:

def human_add(request):
    if request.method == 'POST':
        human_form = HumanForm(request.POST)
        location_form = LocationForm(request.POST)
        human_notes_form = HumanNotesForm(request.POST)

        if human_form.is_valid() and location_form.is_valid() and human_notes_form.is_valid():
            human_form.save(commit=False)
            location_form.save()
            locationKey = location_form.id  
            human_notes_form.save(commit=False)
            human_notes_form.intaker = request.user
            human_notes_form.save()
            noteKey = human_notes_form.id
            human_form.location = locationKey
            human_form.note = noteKey
            human_form.intaker = request.user 
            human_form.save()
            return redirect('/intake/success-form') 
        else:
            context = {
                'human_form': human_form,
                'location_form': location_form,
                'human_notes_form': human_notes_form,
            }
    else:
        context = {
            'human_form': HumanForm(),
            'location_form': LocationForm(),
            'human_notes_form': HumanNotesForm(),
        }
    return render(request, 'intake/human-add.html', context)

The only error I am getting is that 'LocationForm' object has no attribute 'id' - but I even added it explicitly (thought I should not have to and don't want it visible):

class HumanNotesForm(forms.ModelForm):
    class Meta:
        model = HumanNotes
        fields = ['id','intaker','note'] 

class LocationForm(forms.ModelForm):
    class Meta:
        model = Location
        fields = ['id','st1','st2','cty','county','state','zip','lat','long','img','img_nm','img_id']  

Any guidance appreciated.

Upvotes: 2

Views: 1102

Answers (1)

Pangolin
Pangolin

Reputation: 31

This did the trick....as did getting excellent guidance from forum.djangoproject.com. Needed to understand the diff between forms and models.

def human_add(request):
    if request.method == 'POST':
        human_form = HumanForm(request.POST)
        location_form = LocationForm(request.POST)
        human_notes_form = HumanNotesForm(request.POST)

        if human_form.is_valid() and location_form.is_valid() and human_notes_form.is_valid():
            loc = location_form.save()
            hum = human_form.save(commit=False) 
            humnote = human_notes_form.save(commit=False)
            hum.intaker = request.user
            hum.location = loc   #.id NOTE YOU NEED THE ENTIRE INSTANCE
            human_form.save()
            humnote.intaker = request.user
            humnote.human = hum #.id NOTE YOU NEED THE ENTIRE INSTANCE
            human_notes_form.save()
            return redirect('/intake/success-form')
        else:
            context = {
                'human_form': human_form,
                'location_form': location_form,
                'human_notes_form': human_notes_form,
            }
    else:
        context = {
            'human_form': HumanForm(),
            'location_form': LocationForm(),
            'human_notes_form': HumanNotesForm(),
        }
    return render(request, 'intake/human-add.html', context)

Upvotes: 1

Related Questions