【问题标题】:Django field doesn't remain incremented even after calling save()即使在调用 save() 之后,Django 字段也不会保持递增
【发布时间】:2015-09-28 18:54:52
【问题描述】:

我已经搜索了所有内容,但找不到答案。我真的不明白为什么这不起作用,尤其是因为它适用于其他项目。无论如何,当用户得到正确的问题时,我试图将模型字段增加 1。我正在使用 Django 1.8 和 Python 3.5,以及 factory_boy 来创建测试数据。

views.py 函数如下:

def check_answer(request):
    front = request.POST.get('front')
    userAnswer = request.POST.get('ans')
    answerCards = Card.objects.filter(front=front)
    for ans in answerCards:
        if ans.back == userAnswer:
            ans.score += 1
            ans.save() # at this point calling print(ans.score) will return 1
            return HttpResponse('correct')
    answerCards.update(score=F('score') - 1) # using print statements I know it isn't hitting this line
    return HttpResponse('wrong')

这是相关的models.py代码:

class Card(models.Model):
    front = models.CharField(max_length=512)
    back = models.CharField(max_length=512)
    deck = models.ForeignKey(Deck)
    score = models.IntegerField(default=0)

    def __repr__(self):
        return self.front + ' - ' + self.back

这里是相关的tests.py代码:

class UserFactory(factory.DjangoModelFactory):
    class Meta:
        model = User

    username = factory.Sequence(lambda n: 'user%d' % n)
    password = factory.Sequence(lambda n: 'pass%d' % n)


class DeckFactory(factory.DjangoModelFactory):
    class Meta:
        model = Deck

    author = factory.SubFactory(UserFactory)
    title = fuzzy.FuzzyText()
    description = fuzzy.FuzzyText()


class CardFactory(factory.DjangoModelFactory):
    class Meta:
        model = Card

    front = fuzzy.FuzzyText()
    back = fuzzy.FuzzyText()
    deck = factory.SubFactory(DeckFactory)
    score = random.randint(-20, 10)


class TestNotecardViews(TestCase):

    def test_add_score_to_card(self):
        # this test passes
        card = CardFactory(score=0)
        card.score += 1
        card.save()
        self.assertEqual(1, card.score)

    def test_check_answer(self):
        deck = DeckFactory.create()
        card = CardFactory.create(front='test',
                                  back='tset',
                                  deck=deck,
                                  score=0)
        # test correct answer
        data = {
                'front': card.front,
                'ans': 'tset',
        }
        resp = self.client.post(reverse('check_answer'), data=data)
        self.assertContains(resp, 'correct', 1) # this test passes
        self.assertEqual(card.score, 1) # this test fails

特别令人沮丧的是,值确实发生了变化,只是在更改它的函数返回后,它并没有保持这种状态,即使在调用 save() 之后也是如此。

【问题讨论】:

    标签: python django python-3.x


    【解决方案1】:

    调用视图后,您需要从数据库中重新加载本地版本的card。否则彼此没有任何关系,card 也无法知道 db 已经更新了。

    resp = self.client.post(reverse('check_answer'), data=data)
    card = Card.objects.get(id=card.id)
    self.assertEqual(card.score, 1)
    

    【讨论】:

    • 成功了!没有意识到你必须像那样重新加载它。现在我知道了,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 2020-06-04
    • 2013-06-18
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多