增加数据库中的IntegerField计数器

时间:2016-06-21 14:04:46

标签: python django django-models models

作为Django的初学者,我尝试制作一个简单的应用程序,它可以让Http响应内容被查看了多少次。 我创建了一个新的Counter模型,在里面添加了IntegerField模型count

class Counter(models.Model):
    count = models.IntegerField(default=0)
    def __int__(self):
        return count

在视图中,我从counter类中创建了变量Counter(),并尝试向counter.count整数添加+1,但是当我尝试保存时,它会给我一个错误该整数无法保存。

所以我尝试了保存课程:

def IndexView(response):
    counter = Counter()
    counter.count = counter.count + 1
    counter.save()
    return HttpResponse(counter.count)

此方法将继续显示1,并且在重新加载后无法更改。

我如何正确更改IntegerField模型,以便在每个视图后更新,即使重新加载服务器也会保存?

1 个答案:

答案 0 :(得分:1)

问题

是的,但是您要在每个请求上创建一个新的Counter对象,该对象再次从0开始,这是您的问题

def IndexView(response):
    counter = Counter() # This creates a new counter each time
    counter.count = counter.count + 1
    counter.save()
    return HttpResponse(counter.count)

您在上面做的事情会导致数据库中出现一堆具有count = 1的Counter对象。

解决方案

下面的示例向您展示如何使用get_or_create()

获取现有Counter对象,并将其递增,或者如果它尚不存在则创建它

首先,我们需要将一个计数器与例如一个页面(或任何东西,但我们需要一些来识别它并从数据库中获取它)

class Counter(models.Model):
    count = models.IntegerField(default=0)
    page = models.IntegerField() # or any other way to identify
                                 # what this counter belongs to

然后:

def IndexView(response):
    # Get an existing page counter, or create one if not found (first page hit)
    # Example below is for page 1

    counter, created = Counter.objects.get_or_create(page=1) 

    counter.count = counter.count + 1
    counter.save()
    return HttpResponse(counter.count)

避免count = count + 1

可能发生的竞争条件

为避免竞争条件,请使用DISPOSE_ON_CLOSE

# When you have many requests coming in,
# this may have outdated value of counter.count:
# counter.count = counter.count + 1

# Using an F expression makes the +1 happen on the database
from django.db.models import F
counter.count = F('count') + 1