低版本django升级到django3.2 提示 DEFAULT_AUTO_FIELD解决办法

当您在Django中定义一个没有指定主键的model时,Django将自动为您创建一个主键。主键设置为整数类型(integer)。如果要覆盖该字段类型,可以在每个模型(model)的基础上执行此操作。

从Django 3.2开始,您现在可以在您的设置(settings)中自定义自动创建的主键的类型。

在Django 3.2中开始新项目时,主键的默认类型设置为BigAutoField,这是一个64位整数(64 bit integer)。但是,早期版本将隐式主键的类型设置为整数(integer)。

这意味着当您升级到3.2版本时,您将开始看到有关您没有显式定义的主键类型的警告。满足Django对显式设置主键类型的要求很容易,但您还需要选择是否要将主键字段类型从整数升级到64位整数。

升级到3.2后,官方文档中的建议是运行以下代码:

python -Wa manage.py test

您应该会看到配置DEFAULT_AUTO_FIELD的警告和提示:

WARNINGS:
blog.BlogPost: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
    HINT: Configure the DEFAULT_AUTO_FIELD setting or the BlogConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.

有几种方法可以解决这个问题。一般说来,它们分为两类:不需要迁移的和需要迁移的。

(一)不需要迁移的解决办法:No migrations 如果您想要最简单的升级路径而不需要迁移,则需要告诉Django将DEFAULT_AUTO_FIELD设置为Autofield,这在幕后是一个IntegerField。有几个地方可以做到这一点。

方法一: 打开项目的settings.py并在文件底部添加下面代码:

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

方法二: 如果您更喜欢在每个应用程序(app)的基础上设置字段类型,而不是整个项目(project),您可以在apps.py中指定这一点。

如果您希望每个应用程序使用不同的自动字段类型,则可能需要执行此操作。对于带有博客应用程序的假设项目,在apps.py中添加default_auto_field行就可以了:

from django.apps import AppConfig

class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.AutoField'
    name = 'blog'

(二)迁移的解决办法:Migrations

如果您不介意创建和运行迁移,那么您可以使用新的BigAutoField。同样,有几种方法可以实现这一点: 方法一: 打开项目的settings.py并将以下内容添加到底部:

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

然后,您需要创建并运行迁移以更新数据库以使用新的字段类型。迁移将改变model上的id字段。要在名为blog的假想应用程序中创建并运行迁移,您需要运行以下命令:

python manage.py makemigrations blog

 python manage.py sqlmigrate blog <migration_number>

方法二: 如上所述,您可以针对每个应用程序(app)配置该设置,因此在apps.py中,您可以将DEFAULT_AUTO_FIELD设置为BigAutoField:

from django.apps import AppConfig

class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'my_app'

并再次为您的应用程序创建和运行迁移。

方法三: 如果您是一个细节控,可以设置每个model的id字段。例如:Blog app可能有一个BlogPost model。您可以在每个model上显式设置一个id字段。 在假设的博客应用程序中,您可以修改blog/models.py

class BlogPost(models.Model):
    id = models.BigAutoField(primary_key=True)
    # ...other fields

如果您愿意,也可以将公共基础模型子类化。如果您有大量的model,或许可以省去一些打字工作。在假设的blog应用程序中,您将定义一个CommonBaseModel ,然后在每个Model中继承它.

from django.db import models

class CommonBaseModel(models.Model):
    id = models.BigAutoField(primary_key=True)

    class Meta:
        abstract = True


# Create your models here.
class BlogPost(CommonBaseModel):
   # ...other fields

在前面两个示例中,如果您希望将主键保留为integer,则可以使用Autofield而不是BigAutoField。但是,您仍然需要进行并运行迁移以保持完全最新,因为您已经更改了模型定义。

总结 Django 3.2允许开发人员定制创建自动主键时使用的字段类型。升级意味着Django会警告您没有设置字段类型。 要使警告静默,您需要在项目、应用程序或模型级别设置默认的自动字段。

评论 1