【问题标题】:Django DB Models F Combined ExpressionDjango DB Models F 组合表达式
【发布时间】:2016-02-13 20:45:00
【问题描述】:
In [1]: from django.db.models import F

In [2]: from forum.models import Post

In [3]: post = Post.objects.get(id=1)

In [4]: post.view_count = F('view_count') + 1

In [5]: post.save()

In [6]: post.view_count

Out[6]: <CombinedExpression: F(view_count) + Value(1)>

In [7]: post = Post.objects.get(id=1)

In [8]: post.view_count

Out[8]: 3

帖子保存后,返回组合表达式。

我想要确切的结果 (3)。

是否可以不用再次调用get方法/refresh_from_db?

【问题讨论】:

    标签: python django database model


    【解决方案1】:

    在 Django 1.8+ 中,您可以使用 refresh_from_db 方法。它不会保存任何 SQL 查询,但您可能会认为代码更好。

    >>> post = Post.objects.get(id=1)
    >>> post.view_count
    2
    >>> post.view_count = F('view_count') + 1
    >>> post.save()
    >>> post.refresh_from_db()
    >>> post.view_count
    3
    

    由于更新发生在数据库中,如果不执行 get()refresh_from_db (这两者都会导致类似的 SQL 查询),就无法在 Django 中获取新值。但是,可以改用update() 来避免最初的get()

    >>> Post.objects.filter(id=1).update(view_count=F('view_count') + 1)
    >>> post = Post.objects.get(id=1)
    >>> post.view_count
    3
    

    【讨论】:

    • 谢谢,刷新或重新加载数据库模型需要时间吗?我像下面这样使用 post.refresh_from_db(fields=['view_count',])
    • 我不确定你的问题是什么。您想知道refresh_from_db()get() 是否需要更长的时间?
    • 不,我不是在比较 get() 和 refresh_from_db()。一般10k用户一次更新值,view count的反应是慢还是正常?
    • 你需要做一些性能测试,我不知道它对 10k 用户的表现如何。
    【解决方案2】:

    来自文档https://docs.djangoproject.com/en/1.7/ref/models/queries/#f-expressions

    Python 永远不会知道封装的 SQL 表达式 post.view_count = F('view_count') + 1 # F('view_count') Django sql expression

    完全由数据库处理。

    因此,在 Python 中对数据库所做的更改都知道您应用的表达式而不是结果。

    你可以直接这样操作:-

    post = Post.objects.filter(id=1)
    post.update(view_count = F('view_count') + 1) 
    

    【讨论】:

    • 它会引发属性错误:AttributeError: 'Post' object has no attribute 'update'。更新将工作查询集对象列表。在 [14] 中:post = Post.objects.filter(id=1) 在 [15] 中:post.update(view_count = F('view_count') + 1) Out[15]:1 在 [16]:post[ 0].view_count Out[16]: 5
    • @Muthuvel 谢谢,我在更新 queryset 时出错了。
    【解决方案3】:

    你为什么不直接写post.view_count += 1

    【讨论】:

    • 如果我们将使用 F(),获取数据库而不是 Python 来完成工作并减少某些操作所需的查询数量参考:docs.djangoproject.com/en/1.7/ref/models/queries/#f-expressions
    • 但既然你想真正获得价值,那么使用F
    • 如果我们使用 F(),我们可以减少查询时间。对吗?
    • 如果你打算拉一个项目没有区别,唯一的区别是内存,所以它对于对象的整个查询很有用,而不仅仅是一个
    • post.view_count = F('view_count') + 1 的优点是它会总是将值加一。如果两个用户同时执行post.view_count += 1,则该值可能会更新 1,而不是 2。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    相关资源
    最近更新 更多