Silly Freak
Silly Freak

Reputation: 4231

Why is my django model not saved?

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

Answers (1)

Silly Freak
Silly Freak

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

Related Questions