Skip to content
Browse files

added form to template. almost there...

  • Loading branch information...
1 parent 2a6c705 commit 6169d400eaeffd9a71f6d8ecdf8ed88b221688a3 @hjwp committed
Showing with 170 additions and 8 deletions.
  1. +4 −2 mysite/fts/test_polls.py
  2. +4 −0 mysite/polls/templates/poll.html
  3. +25 −2 mysite/polls/tests.py
  4. +3 −1 mysite/polls/views.py
  5. +134 −3 tutorial04.rst
View
6 mysite/fts/test_polls.py
@@ -72,10 +72,12 @@ def test_voting_on_a_new_poll(self):
self.assertIn('No-one has voted on this poll yet', body.text)
# He also sees a form, which offers him several choices.
- choices = self.browser.find_elements_by_css_selector(
+ choice_inputs = self.browser.find_elements_by_css_selector(
"input[type='radio']"
)
- choices_text = [c.text for c in choices]
+ self.assertEquals(len(choice_inputs), 3)
+ choice_labels = choice_inputs = self.browser.find_elements_by_tag_name('label')
+ choices_text = [c.text for c in choice_labels]
self.assertEquals(choices_text, [
'Very awesome',
'Quite awesome',
View
4 mysite/polls/templates/poll.html
@@ -5,6 +5,10 @@
<h2>{{poll.question}}</h2>
<p>No-one has voted on this poll yet</p>
+
+ <h3>Add your vote</h3>
+ {{form.as_p}}
+
</body>
</html>
View
27 mysite/polls/tests.py
@@ -114,20 +114,43 @@ def test_root_url_shows_links_to_all_polls(self):
class TestSinglePollView(TestCase):
def test_page_shows_poll_title_and_no_votes_message(self):
- # set up two polls, to check the right one is displayed
+ # set up two polls, to check the right one gets used
poll1 = Poll(question='6 times 7', pub_date='2001-01-01')
poll1.save()
- poll2 = Poll(question='life, the universe and everything', pub_date='2001-01-01')
+ choice1 = Choice(poll=poll1, choice='42', votes=0)
+ choice1.save()
+ choice2 = Choice(poll=poll1, choice='The Ultimate Answer', votes=0)
+ choice2.save()
+ poll2 = Poll(question='time', pub_date='2001-01-01')
poll2.save()
+ choice3 = Choice(poll=poll2, choice='PM', votes=0)
+ choice3.save()
+ choice4 = Choice(poll=poll2, choice="Gardener's", votes=0)
+ choice4.save()
client = Client()
response = client.get('/poll/%d/' % (poll2.id, ))
+ # check we use the right template
self.assertEquals(response.templates[0].name, 'poll.html')
+
+ # check we've passed the right poll into the context
self.assertEquals(response.context['poll'], poll2)
+
+ # check the poll's question appears on the page
self.assertIn(poll2.question, response.content)
+
+ # check our 'no votes yet' message appears
self.assertIn('No-one has voted on this poll yet', response.content)
+ # check we've passed in a form of the right type
+ self.assertTrue(isinstance(response.context['form'], PollVoteForm))
+
+ # and check the check the form is being used in the template,
+ # by checking for the choice text
+ self.assertIn(choice3.choice, response.content)
+ self.assertIn(choice4.choice, response.content.replace('&#39;', "'"))
+
class TestPollsVoteForm(TestCase):
View
4 mysite/polls/views.py
@@ -1,6 +1,7 @@
from django.shortcuts import render
from django.http import HttpResponse
from polls.models import Poll
+from polls.forms import PollVoteForm
def polls(request):
context = {'polls': Poll.objects.all()}
@@ -8,4 +9,5 @@ def polls(request):
def poll(request, poll_id):
poll = Poll.objects.get(pk=poll_id)
- return render(request, 'poll.html', {'poll': poll})
+ form = PollVoteForm(poll=poll)
+ return render(request, 'poll.html', {'poll': poll, 'form': form})
View
137 tutorial04.rst
@@ -84,11 +84,19 @@ Let's work on the unit tests for the ``poll`` view then:
client = Client()
response = client.get('/poll/%d/' % (poll2.id, ))
- self.assertEquals(response.templates[0].name, 'poll.html')
+ # check we've passed the right poll into the context
self.assertEquals(response.context['poll'], poll2)
+
+ # check the poll's question appears on the page
self.assertIn(poll2.question, response.content)
+
+ # check our 'no votes yet' message appears
self.assertIn('No-one has voted on this poll yet', response.content)
+ # check we've passed in a form of the right type
+ self.assertTrue(isinstance(response.context['form'], PollVoteForm))
+
+
Running the tests gives::
TypeError: poll() takes no arguments (2 given)
@@ -406,7 +414,130 @@ HTML actually looks like, why not temporarily put a ``print form.as_p()`` at
the end of the test? Print statements in tests can be very useful for
exploratory programming... You could try ``form.as_table()`` too if you like...
+Right, where where we? Let's do a quick check of the functional tests
+(incidentally, are you rather bored of watching the FT run through the
+admin test each time? I was, so I've built in a second argument to the FT
+runner that lets you filter by name of test - just pass in ``polls`` and
+it will only run FTs in files whose names contain the world ``polls``.)::
+
+ ./functional_tests.py polls
+ [...]
+ AssertionError: Lists differ: [] != ['Very awesome', 'Quite awesom...
+
+Ah yes, we still haven't actually used the form yet! Let's go back to
+our ``TestSinglePollView``, and add some extra code (you can copy and
+paste some of it from the form test)
+
+.. sourcecode:: python
+
+ def test_page_shows_poll_title_and_no_votes_message(self):
+ # set up two polls, to check the right one gets used
+ poll1 = Poll(question='6 times 7', pub_date='2001-01-01')
+ poll1.save()
+ choice1 = Choice(poll=poll1, choice='42', votes=0)
+ choice1.save()
+ choice2 = Choice(poll=poll1, choice='The Ultimate Answer', votes=0)
+ choice2.save()
+ poll2 = Poll(question='time', pub_date='2001-01-01')
+ poll2.save()
+ choice3 = Choice(poll=poll2, choice='PM', votes=0)
+ choice3.save()
+ choice4 = Choice(poll=poll2, choice="Gardener's", votes=0)
+ choice4.save()
+
+ client = Client()
+ response = client.get('/poll/%d/' % (poll2.id, ))
+
+ # check we use the right template
+ self.assertEquals(response.templates[0].name, 'poll.html')
+
+ # check we've passed the right poll into the context
+ self.assertEquals(response.context['poll'], poll2)
+
+ # check the poll's question appears on the page
+ self.assertIn(poll2.question, response.content)
+
+ # check our 'no votes yet' message appears
+ self.assertIn('No-one has voted on this poll yet', response.content)
+
+ # check we've passed in a form of the right type
+ self.assertTrue(isinstance(response.context['form'], PollVoteForm))
+
+ # and check the check the form is being used in the template,
+ # by checking for the choice text
+ self.assertIn(choice3.choice, response.content)
+ self.assertIn(choice4.choice, response.content)
+
+Now the unit tests give us::
+
+ KeyError: 'form'
+
+So back in ``views.py``:
+
+.. sourcecode:: python
+
+ def poll(request, poll_id):
+ poll = Poll.objects.get(pk=poll_id)
+ return render(request, 'poll.html', {'poll': poll, 'form': None})
+
+Now::
+
+ self.assertTrue(isinstance(response.context['form'], PollVoteForm))
+ AssertionError: False is not true
+
+So:
+
+.. sourcecode:: python
+
+ def poll(request, poll_id):
+ poll = Poll.objects.get(pk=poll_id)
+ form = PollVoteForm(poll=poll)
+ return render(request, 'poll.html', {'poll': poll, 'form': form})
+
+And::
+
+ self.assertIn(choice3.choice, response.content)
+ AssertionError: 'PM' not found in '<html>\n <body>\n <h1>Poll Results</h1>\n \n <h2>time</h2>\n\n <p>No-one has voted on this poll yet</p>\n \n </body>\n</html>\n'
+
+So, in ``polls/templates/poll.html``:
+
+.. sourcecode:: html+django
+
+ <html>
+ <body>
+ <h1>Poll Results</h1>
+
+ <h2>{{poll.question}}</h2>
+
+ <p>No-one has voted on this poll yet</p>
-<notes for later:>
-https://docs.djangoproject.com/en/1.3/ref/forms/fields/#modelchoicefield
+ <h3>Add your vote</h3>
+ {{form.as_p}}
+
+
+ </body>
+ </html>
+
+And re-running the tests - oh, a surprise!::
+
+ self.assertIn(choice4.choice, response.content)
+ AssertionError: "Gardener's" not found in '<html>\n <body>\n <h1>Poll Results</h1>\n \n <h2>time</h2>\n\n <p>No-one has voted on this poll yet</p>\n\n <h3>Add your vote</h3>\n <p><label for="id_vote_0">Vote:</label> <ul>\n<li><label for="id_vote_0"><input type="radio" id="id_vote_0" value="3" name="vote" /> PM</label></li>\n<li><label for="id_vote_1"><input type="radio" id="id_vote_1" value="4" name="vote" /> Gardener&#39;s</label></li>\n</ul></p>\n\n \n </body>\n</html>\n'
+
+Django has converted an apostrophe (``'``) into an html-compliant ``&#39;`` for
+us. I suppose that's my come-uppance for trying to include British in-jokes in
+my tutorial. Let's implement a minor hack in our test:
+
+
+.. sourcecode:: html+django
+
+ self.assertIn(choice4.choice, response.content.replace('&#39;', "'"))
+
+And now we have passination::
+
+ ........
+ ----------------------------------------------------------------------
+ Ran 8 tests in 0.016s
+
+ OK
+So let's ask the FTs again!

0 comments on commit 6169d40

Please sign in to comment.
Something went wrong with that request. Please try again.