zinon
zinon

Reputation: 4664

Django: Save foreign key value in a forms raise an error

I have to tables correlated with a foreign key.

Demographics tables with primary key patient_id (required) and diagnosis having foreign key patient. I've created two forms. I save the fields on first form and then the patient field is autocompleted in diagnosis form.

The problem, is when I'm trying to save the fields' values on diagnosis form, I get an error on the first form which says 'This field is required' even this field's value was stored a minute ago.

Edited: This is my solution

input.html (template)

<form class="form-horizontal" method="post">
    {% csrf_token %}
    <div class="tabbable">
        <ul class="nav nav-tabs">
            <li class="active">
                <a href="#1" data-toggle="tab">Demographics</a>
            </li>
            <li>
                <a href="#2" data-toggle="tab">Diagnosis</a>
            </li>
            <li>
                <a href="#3" data-toggle="tab">A_b_sickle</a>
            </li>
        </ul>
        <div class="tab-content">
            <div class="tab-pane fade in active" id="1">
                <input type="hidden" name="form_id" value="demographics">
                <p>{%crispy frm%}</p>

            </div>
            <div class="tab-pane fade" id="2">
                <!-- form controls to be continued here -->
                <input type="hidden" name="form_id" value="diagnosis">
                {%crispy frm_d%}
                <p>Howdy, I'm in Section 2.</p>
            </div>
            <div class="tab-pane fade" id="3">
                <!-- form controls to be continued here -->
                <input type="hidden" name="form_id" value="a_b_s">
                {%crispy frm_a_b_s%}
                <p>Howdy, I'm in Section 3.</p>
            </div>
        </div>
    </div>
    <!--<input type="submit" name='submit' value="Submit">-->
</form>

My view.py contains:

def input(request):

    if request.method == 'POST':
    my_demographics = DemographicForm(request.POST, prefix="demo")
    my_diagnosis = DiagnosisForm(request.POST, prefix='diag')
    my_a_b_sickle= A_b_sickle_thalForm(request.POST,prefix='a_b_s')

    if my_demographics.is_valid() and my_diagnosis.is_valid() and my_a_b_sickle.is_valid:
        my_demographics_object = my_demographics.save()
        my_diagnosis_object = my_diagnosis.save(commit=False)
        my_diagnosis_object.patient = my_demographics_object
        my_diagnosis_object.save()

        my_a_b_sickle_object = my_a_b_sickle.save(commit=False)
        my_a_b_sickle_object.patient = my_demographics_object

        my_a_b_sickle_object.save()

    else:
    my_demographics = DemographicForm(prefix='demo')
    my_diagnosis = DiagnosisForm(prefix='diag')
    my_a_b_sickle= A_b_sickle_thalForm(prefix='a_b_s')

return render_to_response('input.html', {'frm':my_demographics, 'frm_d': my_diagnosis, 'frm_a_b_s': my_a_b_sickle}, context)

models.py

class demographic(models.Model):
    national_health_care_pat_id = models.IntegerField('National Health Care patient id', null=True,blank=True)
    patient_hospital_file_number = models.IntegerField(null=True,blank=True)
    patient_id = models.IntegerField(unique= True ,primary_key=True)

    def __str__(self):
        return str(self.patient_id)

class diagnosis(models.Model):
    patient = models.ForeignKey(demographic)
    age_of_diagnosis = models.IntegerField(null=True,blank=True)

    def __str__(self):
        return str(self.patient_id)

forms.py

class DemographicForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(DemographicForm, self).__init__(*args, **kwargs)
        self.helper=FormHelper(self)
        self.fields['date_of_birth'].widget = widgets.AdminDateWidget()
        self.helper.layout = Layout(
            'national_health_care_pat_id',
            'patient_hospital_file_number',
            'patient_id',

            FormActions(
                Submit('submit', "Save changes"),
                Submit('cancel', "Cancel")
            ),

        )
        self.helper.form_tag = False
        self.helper.form_show_labels = True

    class Meta:
        model = demographic
        exclude = []

class DiagnosisForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(DiagnosisForm, self).__init__(*args, **kwargs)
        self.helper=FormHelper(self)
        self.helper.layout = Layout(
            'patient',
            'age_of_diagnosis',

            FormActions(
                Submit('submit', "Save changes"),
               Submit('cancel',"Cancel")
            ),
        )
        self.helper.form_tag = False
        self.helper.form_show_labels = True

    class Meta:
        model = diagnosis
        exclude = []

Do you have any idea what the problem might be? Thank you in advance!

Upvotes: 0

Views: 2064

Answers (1)

Brandon Taylor
Brandon Taylor

Reputation: 34593

You need to pass in the actual demographic object instead of just the ID for your DiagnosisForm. Django expects ForeignKey fields to point to an instance of the object they represent. You'll also need to exclude the patient field from your DiagnosisForm. This will prevent Django from trying to validate the field.

# forms.py

class DiagnosisForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        . . .

    class Meta:
        model = diagnosis
        exclude = ['patient']


# views.py

from django.shortcuts import get_object_or_404, render
from your_app.models import Patient

def input(request):
    patient = get_object_or_404(Patient, id=5)
    my_demographics = DemographicForm(request.POST or None)
    my_diagnosis = DiagnosisForm(request.POST or None)

    if request.method =='POST':
        if my_demographics.is_valid() and my_diagnosis.is_valid():
            demographic = my_demographics.save()
            my_diagnosis.save(commit=False)
            my_diagnosis.patient = demographic
            my_diagnosis.save()

    return render(request, 'input.html', {'frm':my_demographics, 'frm_d': my_diagnosis})

Upvotes: 2

Related Questions