1. 程式人生 > 其它 >Django 3.2 中有關DEFAULT_AUTO_FIELD的專題

Django 3.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。有幾個地方可以做到這一點

(方法一)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會警告您沒有設定欄位型別。

要使警告靜默,您需要在專案、應用程式或模型級別設定預設的自動欄位。