Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Basics Test Time Django TDD

nicole lumpkin
PLUS
nicole lumpkin
Courses Plus Student 5,328 Points

Failing last Assertion in the last test.AssertionError:False is not True: Couldn't find '<Sedated>by<Rmones> in response

Would someone check out my performer_detail.html file and see why I'm failing the last assertion in the last test.

self.assertContains(resp, str(self.song))

Thanks in advance! I soooo want to pass this course!

songs/models.py
from django.db import models

class Performer(models.Model):
    name = models.TextField()

    def __str__(self):
        return self.name


class Song(models.Model):
    title = models.CharField(max_length=255)
    artist = models.CharField(max_length=255)
    performer = models.ForeignKey(Performer)
    length = models.IntegerField(default=0)

    def __str__(self):
        return "<{}>by<{}>".format(self.title, self.artist)
songs/views.py
from django.shortcuts import render

from .models import Song, Performer


def song_list(request):
    songs = Song.objects.all()
    return render(request, 'songs/song_list.html', {'songs':songs})

def song_detail(request, pk):
    song = Song.objects.get(pk=pk)
    return render(request, 'songs/song_detail.html', {'song':song})

def performer_detail(request, pk):
    performer = Performer.objects.get(pk=pk)
    return render(request, 'songs/performer_detail.html', {'performer':performer})
songs/templates/songs/performer_detail.html
{% extends 'base.html' %}

{% block title %}{{ performer }}{% endblock %}

{% block content %}
<h2>{{ performer }}</h2>
{{ performer.song_set.all|linebreaks }}
{% endblock %}
nicole lumpkin
nicole lumpkin
Courses Plus Student 5,328 Points

PS. Please ignore the un-Python-like training 'f' at the end of performer_detail. I'm not sure how that got there but I've double checked, it does not exist in my Workspace file and I am sure I am passing all but the last assertion in the last test in tests.py. I commented out self.assertContains(resp, str(self.song)) and all the other tests pass. Thanks!!

UPDATE: I have removed the aforementioned 'f' so it's not a distraction to resolving this inquiry

nicole lumpkin
nicole lumpkin
Courses Plus Student 5,328 Points

tests.py

from django.core.urlresolvers import reverse
from django.test import TestCase


from .models import Performer, Song


class PerformerModelTests(TestCase):
    def test_performer_string(self):
        '''String version of Performer should be Performer's name attribute'''
        perf = Performer.objects.create(name='Mike the Frog')
        self.assertEqual(str(perf), perf.name)


class SongModelTests(TestCase):
    def setUp(self):
        self.performer = Performer.objects.create(name='Andrew Chalkley')

    def test_song_string(self):
        '''String version of Song should contain the title and artist'''
        song = Song.objects.create(
            title="Don't Stop Believing",
            artist="Journey",
            length=250,
            performer=self.performer)
        self.assertIn(song.title, str(song))
        self.assertIn(song.artist, str(song))


class ViewTests(TestCase):
    def setUp(self):
        self.performer = Performer.objects.create(name='Craig Dennis')
        self.song = Song.objects.create(
            title='I Wanna Be Sedated',
            artist='The Ramones',
            length=149,
            performer=self.performer)

    def test_song_list_view(self):
        '''The song_list view should:
           * return a 200
           * have self.song in the context
           * use the songs/song_list.html template
        '''
        resp = self.client.get(reverse('songs:list'))
        self.assertEqual(resp.status_code, 200)
        self.assertIn(self.song, resp.context['songs'])
        self.assertTemplateUsed(resp, 'songs/song_list.html')

    def test_song_detail_view(self):
        '''The song_detail view should:
           * return a 200
           * have self.song in the context
           * use the songs/song_detail.html template
        '''
        resp = self.client.get(reverse('songs:detail',
                                       kwargs={'pk': self.song.pk}))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.context['song'], self.song)
        self.assertTemplateUsed(resp, 'songs/song_detail.html')

    def test_performer_detail_view(self):
        '''The performer_detail view should:
           * return a 200
           * have self.performer in the context
           * use the songs/performer_detail.html template
           * show the string version of self.song in the template
        '''
        resp = self.client.get(reverse('songs:performer',
                                       kwargs={'pk': self.performer.pk}))
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.context['performer'], self.performer)
        self.assertTemplateUsed(resp, 'songs/performer_detail.html');print(resp.content)
        self.assertContains(resp, str(self.song))

3 Answers

nicole lumpkin
PLUS
nicole lumpkin
Courses Plus Student 5,328 Points

Guess what ya'll! With a little help from a developer friend of mine, we figured it out! It turns out that Django was turning my greater than/less than characters('<title> by <artist>' ), to &gt; and &lt; respectively. I'm a noob, but he explained that those characters essentially were being escaped and transformed into the strings in bold. So when self.assertContains(resp, str(self.song)) went looking for '<I Wanna Be Sedated> by <The Ramones>', it found '&gt;I Wanna Be Sedated&lt;by&gt;The Ramones&lt;' BUT, if you use the filter safe it prevents this! Check out my passing performer_detail.html!!!

{% extends 'base.html' %}

{% block title %}{{ performer }}{% endblock %}

{% block content %}
<h2>{{ performer }}</h2>
{{ performer.song_set.all|safe|linebreaks }}
{% endblock %}

This also passes!!!

{% extends 'base.html' %}

{% block title %}{{ performer }}{% endblock %}

{% block content %}
<h2>{{ performer }}</h2>
{% for song in performer.song_set.all %}
{{ song|safe }}
{% endblock %}

WHOOP WHOOP!!

Stuart Wright
Stuart Wright
41,120 Points

I don't know Django, but the f on the end of this line doesn't look like any Python I've ever seen - is this causing a syntax error perhaps?

return render(request, 'songs/performer_detail.html', {'performer':performer})f
nicole lumpkin
nicole lumpkin
Courses Plus Student 5,328 Points

Hi Stuart Wright I'm not sure how that 'f' got there, it's not there in Workspaces. That's probably why I'm failing on the actual TreeHouse site since that's what loads on this page. But I'm failing in Workspaces sans mystery 'f'

Stuart Wright
Stuart Wright
41,120 Points

Ah ok, I guess there must be something else wrong then which I'm afraid I'm not qualified to comment on. Seems somebody has asked about this challenge before though so you might find this useful:

https://teamtreehouse.com/community/copy-and-paste-your-models-views-and-performer-template-from-workspaces-into-the-correct-files-below-2

nicole lumpkin
nicole lumpkin
Courses Plus Student 5,328 Points

Hey thanks for directing me to that. I didn't come across that particular post. It seems like they didn't appreciate my use of the 'linebreaks' filter! So I've started the same line of inquiry on that thread. Hopefully I'll get to the bottom of this!

Henrik Christensen
seal-mask
.a{fill-rule:evenodd;}techdegree
Henrik Christensen
Python Web Development Techdegree Student 38,322 Points

Reading this docstring '''String version of Song should contain the title and artist''' I'm wondering what would happen if you use self.assertContains() instead of self.assertIn()?

nicole lumpkin
nicole lumpkin
Courses Plus Student 5,328 Points

I'm not sure if that would change things, but these are the tests provided by TreeHouse. So the change may get the code to pass in Workspaces, but it would fail when trying to pass the actual challenge. Thanks Henrik Christensen , if you read my answer below you'll see that I've (okay okay I had help!!) found a solution!!!