更新 Django 3.2 解决 DEFAULT_AUTO_FIELD warnings

作者:admin 发布日期:2021年11月11日 10:06

当您在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。有几个地方可以做到这一点

(方法一)Configure DEFAULT_AUTO_FIELD in settings,打开项目的settings.py并在文件底部添加新行

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'


(方法二)Setting on a per app basis
如果您更喜欢在每个应用程序(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。同样,有几种方法可以实现这一点:

(1)Configure DEFAULT_AUTO_FIELD in settings to use 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>


(2)Set default_auto_field to BigAutoField on a per app basis
如上所述,您可以针对每个应用程序(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'


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

(3)Set AutoField or BigAutoField on a per model basis
如果您喜欢更细粒度的控制,可以设置每个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会警告您没有设置字段类型。

要使警告静默,您需要在项目、应用程序或模型级别设置默认的自动字段。

文章标签: python django
本篇共 0 条评论

留言内容:

还没有任何评论!

还没有登陆,请登录后发表评论!
文章目录