Django模型未更新

时间:2016-12-07 18:24:10

标签: python django

我试图计算用户访问网页的次数:

models.py:

class Request(models.Model):
    user = models.ForeignKey(User)
    view = models.CharField(max_length = 250)
    visits = models.PositiveIntegerField()

views.py

def daygaps(request,*a, **kw):

    request_counter = Request.objects.filter(
        user__username = request.user.username, view = 'daygaps')

    if request_counter:
        request_counter[0].visits += 1
        request_counter.update()

    else:
        Request.objects.create(
            user = request.user,
            visits = 1,
            view = 'daygaps')

当新用户第一次访问该网页时,访问'设置为= 1.每次后续访问都应该迭代计数。 "其他"块工作正常,然而"访问"保持在1,并且不会随着用户的每个新请求而改变。

我已经尝试过" .save()"方法,但是会引发错误,因为" request_counter"是一个查询集。

2 个答案:

答案 0 :(得分:4)

你可以这样做:

models.py

class Request(models.Model):
    user = models.ForeignKey(User)
    view = models.CharField(max_length = 250)
    visits = models.PositiveIntegerField(default=0)

views.py

def daygaps(request,*a, **kw):

    request_counter = Request.objects.get_or_create(
        user = request.user, view = 'daygaps')

    request_counter.visits += 1 # or =F('visits')+1 to avoid a race condition as suggested by Moses Koledoye
    request_counter.save()

OR

models.py

class Request(models.Model):
    user = models.ForeignKey(User)
    view = models.CharField(max_length = 250)
    visits = models.PositiveIntegerField(default=1)

views.py

def daygaps(request,*a, **kw):

    updated_count = Request.objects\
        .filter(user = request.user, view = 'daygaps')\
        .update(visits=F('visits')+1)

    if not updated_count:
        Request.objects.create(user = request.user, view = 'daygaps')

它也避免了竞争条件,并且具有无需检索对象的附加优势。

一般情况下,如果更新足够简单,可以使用F表达式来实现第二个更好。

答案 1 :(得分:4)

您可以简单地使用filter返回对象,而不是使用.get并对QuerySet返回的列表建立索引:

from django.db.models import F

def daygaps(request,*a, **kw):
    ...
    request_counter = Request.objects.get(
        user__username = request.user.username, view = 'daygaps')
    request_counter.visits = F('visits') + 1
    request_counter.save()

您可以将逻辑包装在try/except中以处理DoesNotExist例外。

F表达式可帮助您管理竞争条件。阅读更多:Updating attributes based on existing fields