在Django中锁定对象的最简单的方法是什么 [英] What is the simplest way to lock an object in Django

查看:428
本文介绍了在Django中锁定对象的最简单的方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当某个其他用户在update_object视图中处于活动状态时,当用户尝试删除对象时,我想引发错误。我觉得需要一些类似互斥锁的机制。你有什么建议吗?

解决方案

所以,有很多方法来做你想要的。但是其中有很多不是与实现无关的:你可以使用锁或者锁,但是他们真的只能在100%的线程服务器上工作,并且可能在fork / pre-fork实现中根本不工作。



这或多或少意味着锁定实现将取决于你。两个想法:


  1. .lock 您的模型类中的b $ b
  2. 锁定属性

case,你必须手动设置锁定对象更新和检查对它删除。尝试类似:

  def safe_update(request,model,id):
obj = model.objects.get id)
if obj.locked:
raise SimultaneousUpdateError#定义这里
else:
obj.lock()
return update_object(request,model,id)

#在模型文件
中类SomeModel(models.Model):
locked = models.BooleanField(default = False)
def lock(self):
self.locked = True
super(models.Model,self).save()
def save(self):
#覆盖保存,因为你想使用通用视图
#可能不是最好的想法重做模型代码以适应视图快捷方式
#但我喜欢给例子。
self.locked = False
#这创建了一个不同的关键区域!
super(models.Model,self).save()

实现,你必须清理。你可能不太喜欢这样一个事实,一个不同的关键区域已经创建,但我不知道如果你使用数据库作为一个实现,而不使实现更复杂,你会做得更好。 (一个选择是使锁完全分离对象,然后你可以在调用save()方法后更新它们,但是我不想编写代码。)如果你真的想使用基于文件的锁系统,这也将解决问题。如果你是数据库命中偏执,这可能是你的事情。类似:

  class FileLock(object):
def __get __(self,obj):
return os.access(obj .__ class __ +_+ obj.id +。lock,os.F_OK)
def __set __(self,obj,value):
如果不是isinstance(value,bool) :
raise AttributeError
如果值:
f = open(obj .__ class __ +_+ obj.id +。lock)
f.close()
else:
os.remove(obj .__ class __ +_+ obj.id +。lock)
def __delete __(self,obj):
raise AttributeError

class SomeModel(models.Model):
locked = FileLock()
def save(self):
super(models.Model,self).save()
self .locked = False

无论如何,也许有一些方法可以混合和匹配这些建议, / p>

I want to raise error when a user tries to delete an object when some other users are active in update_object view. I feel some sort of mutex-like locking mechanism is needed for that. Do you have any suggestions?

解决方案

So, there are a handful of ways to do what you're asking. But a good number of them are not going to be implementation independent: you could use locks or rlocks, but they will really only work on 100% threaded servers and probably not at all in a fork/pre-fork implementation.

That more or less means the locking implementation will be up to you. Two ideas:

  1. .lock file on your file system
  2. locked property in your model class

In both cases, you have to manually set the lock object on update and check against it on delete. Try something like:

def safe_update(request,model,id):
    obj = model.objects.get(id)
    if obj.locked:
        raise SimultaneousUpdateError #Define this somewhere
    else:
        obj.lock()
        return update_object(request,model,id)

# In models file
class SomeModel(models.Model):
    locked = models.BooleanField(default = False)
    def lock(self):
        self.locked = True
        super(models.Model,self).save()
    def save(self):
        # overriding save because you want to use generic views
        # probably not the best idea to rework model code to accomodate view shortcuts
        # but I like to give examples.
        self.locked = False
        # THIS CREATES A DIFFERENT CRITICAL REGION!
        super(models.Model,self).save()

This is indeed a clumsy implementation that you'll have to clean up. You may not be comfortable with the fact that a different critical region has been created, but I don't see how you'll do much better if your using the database as an implementation without making the implementation much more complicated. (One option would be to make the locks entirely separate objects. Then you could update them after the save() method is called. But I don't feel like coding that up.) If you really want to use a file-based locking system, that would also solve the problem. If you're database-hit-paranoid, this might be the thing for you. Something like:

class FileLock(object):
    def __get__(self,obj):
        return os.access(obj.__class__+"_"+obj.id+".lock",os.F_OK)
    def __set__(self,obj,value):
        if not isinstance(value,bool):
            raise AttributeError
        if value:
            f = open(obj.__class__+"_"+obj.id+".lock")
            f.close()
        else:
            os.remove(obj.__class__+"_"+obj.id+".lock")
    def __delete__(self,obj):
        raise AttributeError

 class SomeModel(models.Model):
     locked = FileLock()
     def save(self):
         super(models.Model,self).save()
         self.locked = False

Anyway, maybe there's some way to mix and match these suggestions to your taste?

这篇关于在Django中锁定对象的最简单的方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆