【问题标题】:Avoiding IntegrityError in custon Django field避免自定义 Django 字段中的 IntegrityError
【发布时间】:2011-09-05 16:58:19
【问题描述】:

假设一个 django 模型有两个字段: - 创建 - 修改的 每个字段都是整数,唯一且价值不断增加。第一次保存时,对象的 created 和 modified 应该具有相同的值,并且修改的字段应该在每次保存时创建到下一个大于自身的空闲值。

我为此目的创建了以下字段:

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 django-models


    【解决方案1】:

    进行线程安全数据库访问的唯一方法是在访问之前锁定表。粗略的在线搜索发现了这个 sn-p:http://djangosnippets.org/snippets/2039/。也许你可以用它做点什么。 Django 文档中关于事务的部分也会对您有用:https://docs.djangoproject.com/en/dev/topics/db/transactions/

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 2015-04-29
      • 2014-08-23
      • 2021-11-20
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多