I've been working my way through the Django tutorial, I'm on part 5 where it asks me to create a test to see if polls without choices are being published or not. For every other test we did, like making sure only polls in the past (and not the future) were published we would simply create two polls: one with a pub_date
in the past and one in the future:
def test_index_view_with_future_poll_and_past_poll(self):
"""
Even if both past and future polls exist, only past polls should be
displayed.
"""
create_poll(question='past poll', days=-30)
create_poll(question='future poll', days=30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_poll_list'],
['<Poll: past poll>'])
For the corresponding view we simply added the following function:
def get_queryset(self):
"""Return the last five published poll."""
#Returns polls published at a date the same as now or before
return Poll.objects.filter(pub_date__lte=timezone.now()).order_by('pub_date')[:5]
It just uses the filter() function to filter out any polls with a pub_date
in the future, which is simple really. But I can't seem to do the same for polls without any choices, this is what I have so far for the testing function:
class PollsAndChoices(TestCase):
""" A poll without choices should not be displayed
"""
def test_poll_without_choices(self):
#first make an empty poll to use as a test
empty_poll = create_poll(question='Empty poll', days=-1)
poll = create_poll(question='Full poll',days=-1)
full_poll = poll.choice_set.create(choice_text='Why yes it is!', votes=0)
#create a response object to simulate someone using the site
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(response.context['latest_poll_list'], ['<Poll: Full poll>'])
And this is what I have for the related view:
class IndexView(generic.ListView):
#We tell ListView to use our specific template instead of the default just like the rest
template_name = 'polls/index.html'
#We use this variable because the default variable for Django is poll_list
context_object_name = 'latest_poll_list'
def get_queryset(self):
"""Return the last five published poll."""
#Returns polls published at a date the same as now or before
return Poll.objects.filter(pub_date__lte=timezone.now()).order_by('pub_date')[:5]
def show_polls_with_choices(self):
""" Only publish polls that have choices """
#Since choice_set displays a list we can use it to make sure a poll with an empty list
#is not published
for poll in Poll.objects.all():
if poll.choice_set.all() is not []:
return poll
Basically nothing is happening, the test is failing:
Traceback (most recent call last):
File "C:\Users\ELITEBOOK\dropbox\programming\mysite\polls\tests.py", line 125, in test_poll_without_choices
self.assertQuerysetEqual(response.context['latest_poll_list'], ['<Poll: Full poll>'])
File "C:\Users\Elitebook\Dropbox\Programming\virtualenvs\project\lib\site- packages\django\test\testcases.py", line 829
, in assertQuerysetEqual
return self.assertEqual(list(items), values)
AssertionError: Lists differ: ['<Poll: Empty poll>', '<Poll:... != ['<Poll: Full poll>']
First differing element 0:
<Poll: Empty poll>
<Poll: Full poll>
First list contains 1 additional elements.
First extra element 1:
<Poll: Full poll>
- ['<Poll: Empty poll>', '<Poll: Full poll>']
+ ['<Poll: Full poll>']
So the app is still publishing both the empty poll and the full poll, is there a way to use the filter()
method to refine polls based on whether or not they have choices?