Django Reverse relation in template renders sporadically

时间:2016-07-28 20:28:36

标签: python django selenium

I'm getting different results from a template when I render it using Selenium in a functional test. Visiting the page normally, I see objects being rendered. During a functional test, the page is blank (it doesn't even render the text in the empty clause.) I wrote a small Django app to test it and make sure I'm not going crazy, and I'm getting the same problem consistently.

The models:

class M(models.Model):
    pass


class N(models.Model):
    m = models.ForeignKey(
        M,
        null=True,
        default=None,
        )

The view:

def view_my_problem(request):
    ms = M.objects.all()
    context = {'ms': ms}
    return render(request, 'my_problem_template.html', context)

The template:

<html>
    {% for m in ms %}
        {% for n in m.n_set.all %}
            {{ n }}
        {% empty %}
            THIS IS EMPTY
        {% endfor %}
    {% endfor %}
</html>

And the test with a problem (fails with "AssertionError: 'N object' not found in ''"):

class FunctionalTest(StaticLiveServerTestCase):

    @classmethod
    def setUpClass(cls):
        for arg in sys.argv:
            if 'liveserver' in arg:
                cls.server_url = 'http://' + arg.split('=')[1]
                return
        super().setUpClass()
        cls.server_url = cls.live_server_url

    @classmethod
    def tearDownClass(cls):
        if cls.server_url == cls.live_server_url:
            super().tearDownClass()

    def setUp(self):
        self.browser = webdriver.Firefox()
        self.browser.implicitly_wait(10)

    def tearDown(self):
        self.browser.close()

    def test_my_problem(self):
        m = M()
        m.save()
        n = N(m=m)
        n.save()
        self.assertEqual(N.objects.count(), 1)
        self.assertEqual(M.objects.count(), 1)
        self.assertEqual(m.n_set.count(), 1)
        text = self.browser.find_element_by_tag_name('html').text
        self.assertIn('N object', text)

But rendering the template manually in a test works fine. And visiting the page like normal (not while running a test) works fine as well. I could just compose the values ahead of time in the view, and then iterate over constants, but I'm curious as to why this doesn't work. What's going on here?

1 个答案:

答案 0 :(得分:0)

self.browser.get(self.live_server_url)
text = ...