【问题标题】:Update a Model Field when DetailView encounter. [Django]遇到 DetailView 时更新 Model Field。 [姜戈]
【发布时间】:2018-04-30 08:17:04
【问题描述】:

我有一个类似于 views.py 的 DetailView:

views.py

class CustomView(DetailView):
    context_object_name = 'content'
    model = models.AppModel
    template_name = 'dynamictemplate.html'

    def get_context_data(self, **kwargs):
        data = super(CustomView, self).get_context_data(**kwargs)
        <...snipped...>
        return data

当来自 urls.py 的请求转移到 views.py 时,我如何更新模型字段 IntegerField。假设 IntegerField 的名称是 clicks 并且当用户访问特定链接或被动访问数据库中的模型对象时,我该如何增加该对象的 clicks 字段1。

【问题讨论】:

    标签: python django url


    【解决方案1】:

    您可以使用self.object 并以这种方式更新它:

    self.object.clicks = self.object.clicks + 1
    self.object.save()
    

    但正如丹尼尔在评论中所说,使用此代码您可以面对race condition。所以最好像这样使用F expressions

    from django.db.models import F
    
    def get_context_data(self, **kwargs):
        data = super(CustomView, self).get_context_data(**kwargs)
        self.object.clicks = F('clicks') + 1
        self.object.save()
        <...snipped...>
        return data
    

    【讨论】:

    • 注意这里的竞争条件;另一个线程可能会在此之前更新相同的数据库行。最好使用F() 对象告诉数据库进行原子更新。
    • 它给了我一个字符串“F('clicks') + Value(1)”的输出。但是,该值成功地增加了 1。您之前的答案对我来说很好。
    • 我可以用这个方法来更新内容吗?如果那么如何?
    【解决方案2】:

    neverwalkaloner 非常接近,但是对象保存后需要从数据库中刷新。

    from django.db.models import F
    
    def get_context_data(self, **kwargs):
        context = super(CustomView, self).get_context_data(**kwargs)
        self.object.clicks = F('clicks') + 1
        self.object.save()
        self.object.refresh_from_db()
        <...snipped...>
        return context
    

    现在将显示点击的值,而不是 F 表达式的 __repr__

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-18
      • 2020-08-17
      • 2021-03-25
      • 2017-09-20
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      • 2017-06-15
      相关资源
      最近更新 更多