gpt4 book ai didi

python - Django 。在不影响其 updated_at 字段的情况下增加对象的查看次数

转载 作者:行者123 更新时间:2023-12-05 05:31:09 24 4
gpt4 key购买 nike

我有以下模型:

class Announcement(models.Model):
...
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
views = models.PositiveIntegerField(default=0, editable=False)

我的看法:

class AnnouncementDetailView(DetailView):
model = Announcement
context_object_name = 'announcement'
template_name = 'web/index.html'

def get(self, *args, **kwargs):
announcement = get_object_or_404(Announcement, id=kwargs['id'])
announcement.views += 1
announcement.save()
return super().get(self, *args, **kwargs)

问题是:

  1. 我知道 F 表达式,我将在下面使用它,但我想知道另一种更新字段而不更新 updated_at 字段的方法。
  2. 我想保存模型的 views 字段的更改,但每次保存它时,它都会将新值设置为 updated_at 字段。这意味着每次我刷新页面时,它都会在 updated_at 字段中显示当前时间,这非常糟糕。

我已将我的 View 代码更改为:

...
def get(self, *args, **kwargs):
Announcement.objects.filter(id=kwargs['id']).update(views=F('views') + 1)
return super().get(self, *args, **kwargs)

现在它工作正常,但我有几个问题。如何在不调用 """"Django"""""的 save 方法的情况下保存 views 字段的新值?我能用它走多远。什么是在不点击保存方法的情况下更改模型某些字段的最佳实践?

最佳答案

一个简单的方法可能是在 .save(…) method [Django-doc] 中指定 update_fields :

class AnnouncementDetailView(DetailView):
model = Announcement
context_object_name = 'announcement'
template_name = 'web/index.html'

def get(self, *args, **kwargs):
try:
return super().get(self, *args, **kwargs)
finally:
object = getattr(self, 'object', None)
if object:
object.views = F('views') + 1
object.save(<b>update_fields=('views',)</b>)

然而,最好使用 F 表达式来避免竞争条件

利用:

Announcement.objects.filter(id=kwargs['id']).update(views=F('views') + 1)

会让数据库进行如下查询:

UPDATE appname_announcementSET view = view + 1WHERE id = id

如果您因此不必将对象加载到内存中,那么效率会更高,因为它只往返于数据库一次。

关于python - Django 。在不影响其 updated_at 字段的情况下增加对象的查看次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74421959/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com