python - 在 Django 模型字段中设置默认值的更好方法

标签 python django orm django-orm

我正在 Django 模型中实现一个字段,它调用以下函数作为默认值

def get_default_value():
    a = MyModel.objects.aggregate(max_id=Max('id'))
    return get_unique_value_based_on_num(a['max_id'] or 0)

class MyModel:
    default_value_field = CharField(default=get_default_value)

虽然我在这方面可能是错的,但我担心这个实现可能会导致竞争条件。

有更好的方法吗?可能使用 F 对象或其他东西?

最佳答案

为避免竞争条件,最好让数据库处理表的完整性,这是数据库的目的之一。

为此,请捕获通过保存模型实例引发的任何 IntegrityError,并在失败时使用不同的值重试。

from django.db import IntegrityError, models, transaction


def get_default_value():
    a = MyModel.objects.aggregate(max_id=Max('id'))
    return get_unique_value_based_on_num(a['max_id'] or 0)

class MyModel(models.Model):
    # Have unicity enforced at database level with unique=True.
    default_value_field = models.CharField(max_length=200, unique=True)

    def save(self):
        if not self.default_value_field:
            max_tries = 100  # Choose a sensible value!
            for i in range(max_tries):
                try:
                    self.default_value_field = get_default_value()

                    # Atomic block to rollback transaction in case of IntegrityError.
                    with transaction.atomic():
                        super(MyModel, self).save()
                        break
                except IntegrityError:
                    # default_value_field is not unique, try again with a new value.
                    continue
            else:
                # Max tries reached, raise.
                raise IntegrityError('Could not save model because etc...')
        else:
            super(MyModel, self).save(*args, **kwargs)

关于python - 在 Django 模型字段中设置默认值的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29804593/

相关文章:

python - 可变长度列表的列表

python - 在 __add__ 运算符中返回相同子类的对象

python - Django使用 `mysql.connector.django`作为数据库ENGINE后,如何打印执行的SQL语句

php - 使用数组更新 Laravel Eloquent ORM

c# - Entity Framework 代码优先 - 来自同一张表的两个外键

python - python追加带有列表的语法错误

python - 0 和 1 之间的余弦相似度

python - 如何在 Django、Varnish、Nginx 中处理数千个遗留 URL?

Django 管理页面使我的模型无法点击

mysql - 如何在我的 django 应用程序中创建 model.py 来实现我的需要?