我有以下模型:
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字段的另一种方法。
1.我想保存对model的views
字段的更改,但是每次保存时,它都会将新值设置为updated_at
字段。这意味着每次刷新页面时,它都会在updated_at字段上显示当前时间,这非常糟糕。
我已将视图的代码更改为:
...
def get(self, *args, **kwargs):
Announcement.objects.filter(id=kwargs['id']).update(views=F('views') + 1)
return super().get(self, *args, **kwargs)
现在它运行的很好,但是我有几个问题。它如何保存views
字段的新值而不调用Django的save方法?我能用它走多远?在不点击save方法的情况下更改模型的一些字段的最佳实践是什么?
1条答案
按热度按时间zpgglvta1#
一个简单的方法就是在**
.save(…)
**方法中指定update_fields
[Django-doc]:但是,最好使用
F
表达式来避免 * 竞态条件 *。利用:
将让数据库进行如下查询:
如果这样就不必将对象加载到内存中,则效率会更高,因为它只对数据库进行一次往返。