递增数据库中的 IntegerField 计数器
Incrementing IntegerField counter in a database
作为 Django 的初学者,我尝试制作一个简单的应用程序,它会给出内容被查看次数的 Http 响应。
我创建了一个新的 Counter
模型,并在内部添加了 IntegerField 模型 count
.
class Counter(models.Model):
count = models.IntegerField(default=0)
def __int__(self):
return count
在视图中,我从 Counter()
class 中创建了一个变量 counter
,并尝试将 +1 添加到 counter.count
整数,但是当我尝试保存时,它会给我一个无法保存整数的错误。
所以我尝试保存 class:
def IndexView(response):
counter = Counter()
counter.count = counter.count + 1
counter.save()
return HttpResponse(counter.count)
此方法,会一直显示1
,重新加载后无法更改。
我如何正确更改 IntegerField
模型,以便在每次查看后更新它,并且即使重新加载服务器也能保存它?
问题
是的,但是您要为每个请求创建一个新的 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 对象。
解决方案
我下面的示例向您展示了如何获取现有的 Counter 对象,并增加它,或者如果它不存在则创建它,get_or_create()
首先我们需要将一个计数器关联到例如一个页面(或任何东西,但我们需要某种方式来识别它并从数据库中获取它)
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
可能发生的竞争条件
并为避免竞争条件使用 F expression
# 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
作为 Django 的初学者,我尝试制作一个简单的应用程序,它会给出内容被查看次数的 Http 响应。
我创建了一个新的 Counter
模型,并在内部添加了 IntegerField 模型 count
.
class Counter(models.Model):
count = models.IntegerField(default=0)
def __int__(self):
return count
在视图中,我从 Counter()
class 中创建了一个变量 counter
,并尝试将 +1 添加到 counter.count
整数,但是当我尝试保存时,它会给我一个无法保存整数的错误。
所以我尝试保存 class:
def IndexView(response):
counter = Counter()
counter.count = counter.count + 1
counter.save()
return HttpResponse(counter.count)
此方法,会一直显示1
,重新加载后无法更改。
我如何正确更改 IntegerField
模型,以便在每次查看后更新它,并且即使重新加载服务器也能保存它?
问题
是的,但是您要为每个请求创建一个新的 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 对象。
解决方案
我下面的示例向您展示了如何获取现有的 Counter 对象,并增加它,或者如果它不存在则创建它,get_or_create()
首先我们需要将一个计数器关联到例如一个页面(或任何东西,但我们需要某种方式来识别它并从数据库中获取它)
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
可能发生的竞争条件
并为避免竞争条件使用 F expression
# 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