Search code examples
pythondjango-formsdjango-testing

Testing with Django client multiple checkboxes


I read recently a book about TDD in Python and figured I could start to follow this pattern.

But the first problem has already appeared and I can't seem to be able to fix it.

HTML form (declared in forms.py)

When I POST and print it, I get the following output:

<QueryDict: {'csrfmiddlewaretoken': ['...'], 'personal_interests': ['3', '1']}>

In order to test this view, into the tests (using Django client) I have already tried so far:

response = self.client.post('/', data={'reading': False, 'investing': True, 'traveling': True})

response = self.client.post('/', {'personal_interests': ['3', '1']})

Also tried as a tuple:

response = self.client.post('/', {'personal_interests': ('3', '1'),})

But none of these, seem to send the data I want to send.

Thanks in advance.

views.py:

def home_page(request):
    default_customer, _ = Customer.objects.get_or_create(name="John", surname="Doe")
    default_customer.interests.clear()
    form = InterestsForm()
    if request.method == 'POST':
        form = InterestsForm(request.POST)
        if form.is_valid():
            for key, value in form.cleaned_data.items():
                for interest in value:
                    filtered_interest, _ = Category.objects.get_or_create(name=interest)
                    default_customer.interests.add(filtered_interest)
            default_customer.save()
            return redirect('/user/'+str(default_customer.id)+'/interests')
        else:
            messages.error(request, "An error has occured. Check all the fields.")
            return redirect('/')
    context = {'form': form}
    return render(request, 'home.html', context)


forms.py:

class InterestsForm(forms.Form):
    personal_interests = forms.ModelMultipleChoiceField(
     widget=forms.CheckboxSelectMultiple,
     queryset=Category.objects.all().order_by('name'),
     required=False,
     label='Interests')

    class Meta:
        model = Category



Solution

  • I have figured where was the error... Test database and normal database are different so I lacked the objects created in the database while testing.

    So all I needed to do was to create the items, and then send the POST

    response = self.client.post('/', {'personal_interests': ['3', '1']}) WORKS where '3' and '1' are the pks of the objects.

    Here is the fixed code.

    
    def test_can_save_a_POST_request(self):
            Customer.objects.get_or_create(name="John", surname="Doe")
            reading_interest, _ = Category.objects.get_or_create(name="reading")
            investing_interest, _ = Category.objects.get_or_create(name="investing")
            traveling_interest, _ = Category.objects.get_or_create(name="traveling")
    
            post_data = {'personal_interests': [str(investing_interest.id),
             str(traveling_interest.id)]}
    
            response = self.client.post('/',
            data=post_data)
    
            new_customer = Customer.objects.first()
            customer_interests = [category.name for category in new_customer.interests.all()]
    
            self.assertNotIn('reading', customer_interests)
            self.assertIn('traveling', customer_interests)
            self.assertIn('investing', customer_interests)