Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在custon-Django字段中避免整数错误_Django_Django Models - Fatal编程技术网

在custon-Django字段中避免整数错误

在custon-Django字段中避免整数错误,django,django-models,Django,Django Models,假设django模型有两个字段: -创造 -修改 每个字段都是整数,唯一且值不断增加。第一次保存时,对象的“创建”和“修改”值应相同,每次保存时,“修改”字段应增加到大于其自身的下一个自由值 为此,我创建了以下字段: class CreatedVerisonField(models.BigIntegerField): update_on_each_save = False def __init__(self, *args, **kwargs): kwargs.s

假设django模型有两个字段: -创造 -修改 每个字段都是整数,唯一且值不断增加。第一次保存时,对象的“创建”和“修改”值应相同,每次保存时,“修改”字段应增加到大于其自身的下一个自由值

为此,我创建了以下字段:

class CreatedVerisonField(models.BigIntegerField):
    update_on_each_save = False

    def __init__(self, *args, **kwargs):
        kwargs.setdefault('editable', False)
        kwargs.setdefault('blank', True)
        kwargs.setdefault('unique', True)
        models.BigIntegerField.__init__(self, *args, **kwargs)

    def pre_save(self, model, add):
        if add or self.update_on_each_save:
            value = self.get_next_value(model)
            setattr(model, self.attname, value)
            return value
        else:
            return super(CreatedVerisonField, self).pre_save(model, add)

    def get_next_value(self, model):
        objs = model.__class__.objects.all()
        fields = self._get_fields(model)
        if objs:
            # new version is max of all version fields + 1
            value = max(objs.aggregate(*map(lambda x: Max(x), fields)).values()) + 1
        else:
            value = 1
        return value

    def _get_fields(self, model):
        fields = []
        for f in model._meta.fields:
            if isinstance(f, CreatedVerisonField):
                fields.append(f.db_column if f.db_column else f.name)
        return fields

class ModifiedVersionField(CreatedVerisonField):
    def __init__(self, *args, **kwargs):
        self.update_on_each_save = True
        CreatedVerisonField.__init__(self, args, kwargs)
使用以下字段的简单测试类:

class TestModel(models.Model):
    created = CreatedVerisonField()
    modified = ModifiedVersionField()

当从多个线程创建和保存TestModel对象时,由于违反了唯一约束,我得到了IntegretyError。看一下添加pre_save代码,很明显这种竞争是存在的。如何修复此问题?

执行线程安全数据库访问的唯一方法是在访问之前锁定表。在线粗略搜索发现了以下代码段:。也许你可以用它做点什么。Django文档中关于交易的部分也将对您有用: