Reputation: 4231
I have this seemingly simple test case in a Django app, which fails:
def test_matches(self):
# setup code...
matches = tournament.match_set.order_by('match_id')
matches[0].winner = 'a'
matches[0].save()
self.assertEqual(matches[0].winner, 'a')
What's the problem?
Upvotes: 0
Views: 34
Reputation: 4231
The problem is that matches
is not simply a list, but a QuerySet
: indexing and slicing a QuerySet
accesses the database, so each matches[0]
returns a fresh match. matches[0].save()
therefore saves an unmodified object.
As @Wtower notes, the relevant doc is found here
The way this should be written is this:
m = matches[0]
m.winner = 'a'
m.save()
self.assertEqual(matches[0].winner, 'a')
alternately, force evaluation of the QuerySet
if that's what you want:
matches = list(tournament.match_set.order_by('match_id'))
or better, if you can identify the match in the database:
matches.filter(match_id=0).update(winner=0)
This way is way shorter, does the update in place without loading data into python and thus eliminates a possible race condition. However, filtering for match_id
is (generally) not the same as indexing into the QuerySet
. (a sliced QuerySet
like matches[0:1]
can't be updated)
Upvotes: 4