在 Django 中使用 UUIDField 不断创建新的迁移

Using UUIDField in Django keeps creating new migrations

我有一个简单的模型::

class HasUUID(models.Model):
      name = models.CharField(max_length=10)
      batchid = models.UUIDField(default=uuid.uuid4(), unique=True)

运行ning makemigrations 给我迁移::

   operations = [
    migrations.CreateModel(
        name='HasUUID',
        fields=[
            ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ('name', models.CharField(max_length=10)),
            ('batchid', models.UUIDField(default=uuid.UUID('79a2d9fe-e1d0-4d4b-884f-fad0bfb14f0f'), unique=True)),
        ],
    ),

]

运行 迁移给我新的 table 没问题。但是我可以 运行 再次进行迁移,然后我得到::

    operations = [
    migrations.AlterField(
        model_name='hasuuid',
        name='batchid',
        field=models.UUIDField(default=uuid.UUID('3b96231c-5848-430b-aa90-b6e41b11fd0a'), unique=True),
    ),

]

虽然我已经忍受了一段时间,但手动删除了不必要的代码,我需要解决它。

所以我认为,在迁移中将默认设置为一个单独的函数,如各种示例所示::

def create_uuid(apps, schema_editor):
      m = apps.get_model('web', 'HasUUID')
      for inst in m.objects.all():
          inst.batchid = uuid.uuid4()
          inst.save()

...

  migrations.CreateModel(
       name='HasUUID',
        fields=[
            ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ('name', models.CharField(max_length=10)),
            ('batchid', models.UUIDField(blank=True, null=True)),

        ],


    ),
    migrations.RunPython(create_uuid),
    migrations.AlterField(
        model_name='hasuuid2',
        name='batchid',
        field=models.UUIDField(default=uuid.uuid4, unique=True)
    ),

同样的问题。所以我尝试在模型中将默认设置为一个单独的函数::

  def create_uuid():
      return uuid.uuid4()


  class HasUUID2(models.Model):
      name = models.CharField(max_length=10)
      batchid = models.UUIDField(default=create_uuid(), unique=True)

这让我进行了这次迁移::

  migrations.CreateModel(
        name='HasUUID3',
        fields=[
            ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ('name', models.CharField(max_length=10)),
            ('batchid', models.UUIDField(default=uuid.UUID('335c3651-b04e-4ed8-a91d-f2da3f53dd8f'), unique=True)),
        ],
    ),

再次,不断产生新的迁移。我也试过没有 unique = True.

我没主意了。其他地方肯定有一些设置或代码,因为我以前使用过 UUID 字段,但我在 Whosebug 上找不到类似的问题。有什么建议吗?

您应该默认传递可调用对象,而不是调用结果,例如:

class HasUUID(models.Model):
      name = models.CharField(max_length=10)
      batchid = models.UUIDField(default=<b>uuid.uuid4</b>, unique=True)

请注意,这里没有没有 paratheses 进行调用,因此我们传递了对uuid4 函数本身的引用。

default=不是一个特定的UUID(当你启动服务器时确定),它应该是创建新对象时确定的值(无需自己指定 batchid)。

通过传递可调用对象,Django 将理解默认值是调用可调用对象的结果,并且会在迁移中对其进行编码。通过调用该函数,您检索调用的 result,并且每次您 运行 makemigrations,Django 都会认为您改变了主意应该是什么默认值(它会首先认为你想使用 '3b96231c-5848-430b-aa90-b6e41b11fd0a' 作为默认值,然后你想使用 '335c3651-b04e-4ed8-a91d-f2da3f53dd8f')。通过传递可调用对象,您传递的默认值保持不变。