Caco Caco - 4 months ago 19
Python Question

Django form test generates error with a foreign key model field

Have a problem testing a filed form. In field that is defined with models.ForeignKey the test generates an error.

The field gender_opt is defined in models.py as

class Patient(models.Model):
gender_opt = models.ForeignKey(GenderOption, null=False, blank=False)


with ForeignKey given by

class GenderOption(models.Model):
gender_txt = models.CharField(max_length=50)


In my forms.py I have

class PatientForm(ModelForm):
class Meta:
model = Patient

fields = [
other fields
'gender_opt'
]

widgets = {
other widgets

'gender_opt': Select(attrs={'class': 'form-control', 'id': 'gender_id', 'required': "",
'data-error': "Gender must be filled"}),
}


and my test.py is

from django.test import TestCase
from django.contrib.auth.models import *

class FormValidation(TestCase):
def test_patient_add_ok(self):
"""test save patient data successfuly"""

data = {u'cpf_id': [u'248.215.628-98'], u'state_txt': [u'RJ'],
u'citizenship_txt': [u'BR'], u'name_txt': [u'Test pacient'],
u'date_birth_txt': [u'15/01/2003'], u'country_txt': [u'BR'],
u'gender_opt': [u'1']}


response = self.client.post('/quiz/patient/new/', data)
errors = response.context['patient_form'].errors


In errors, I got the follow message:

Select a valid choice. That choice is not one of the available choices.


The URL '/quiz/patient/new/' in test.py points to the view (in views.py)

def patient_create(request, template_name="quiz/register.html"):

gender_options = GenderOption.objects.all()

patient_form = PatientForm()

if request.method == "POST":

patient_form = PatientForm(request.POST)

if patient_form.is_valid():
new_patient = patient_form.save(commit=False)
new_patient.save()



context = {'patient_form': patient_form,
'gender_options': gender_options,
}

return render(request, template_name, context)


I suppose the problem is models.ForeignKey field type.

Appreciate any help.

Answer

First you need to create a GenderOption object. Also, you don't actually need to make a request using self.client while you are testing a form:

class FormValidation(TestCase):
    def test_patient_add_ok(self):
        """test save patient data successfully"""

        # create GenderOption
        gender_opt = GenderOption.objects.create(gender_txt='M')

        data = {u'cpf_id': [u'248.215.628-98'], u'state_txt': [u'RJ'], 
                u'citizenship_txt': [u'BR'], u'name_txt': [u'Test pacient'],
                u'date_birth_txt': [u'15/01/2003'], u'country_txt': [u'BR'],
                u'gender_opt': [str(gender_opt.id)]}

        form = PatientForm(data=data)
        self.assertTrue(form.is_valid())
        ...