您的位置:首页 > 编程语言 > Go语言

Django中的F表达式来解决丢失修改问题

2016-03-01 19:28 381 查看
在使用django开发自己的博客的时候,有一个就是统计每一片博文的访问次数。一开始是这样实现的:

def readArticle(req,article_id):
article = Article.objects.get(id=article_id)
article.read_time+=1 #read_time就是一片博文的访问次数
article.save()
return render(req,"article.html",{'post':article,'post_read_time':post_read_time})#把值传到模板中


后来越想越觉得不对。如果两个用户,在第一个用户访问,代码执行到article.save()之前,第二个用户开始访问了,这样,第一个用户的加一操作会被第二个用户的操作覆盖,这就是所谓的“丢失修改”问题。

后来查阅了很多文档,终于还是在Django的官方文档中发现了F表达式这个东西。这个东西就是用于代表参数中的属性的值。

官方文档如此介绍:

from django.db.models import F

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()


Although
reporter.stories_filed
= F('stories_filed')
+ 1
looks like anormal Python assignment of value to an instance attribute, in fact it’s an SQLconstruct describing an operation on the database.

When Django encounters an instance of
F()
, it overrides the standard Pythonoperators to create an encapsulated SQL expression; in this case, one whichinstructs the database to increment the database
field represented by
reporter.stories_filed
.

Whatever value is or was on
reporter.stories_filed
, Python never gets toknow about it - it is dealt with entirely by the database. All Python does,through Django’s
F()
class, is create the SQL syntax to refer to the fieldand describe the operation.

意思就是,一旦遇到F表达式,Django就会直接在数据库层面进行操作,而不会先把那个属性的值读到内存。事实上,Django是完全不知道那一个值的大小,因为所有动作都是在数据库上进行的。

所以,我的代码要改写成这样:

def readArticle(req,article_id):
article = Article.objects.get(id=article_id)
post_read_time=article.read_time+1
article.read_time=F('read_time')+1
article.save()
return render(req,"article.html",{'post':article,'post_read_time':post_read_time})


这样就不会出现“丢失修改”问题了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: