問題

當我更改Django Model的verbose_name屬性時,Django將生成相關的遷移(執行make migrations命令).

但是,在不應用遷移(migrate命令)的情況下,更改似乎全部應用於Django專案.我認為這是因為verbose_name是在Django級別而不是在資料庫級別使用的東西.

這讓我想知道:這個遷移檔案的目的是什麼?

  最佳答案

Django對所使用的後端進行抽象.實際上,可以透過更改settings.py檔案來使用不同的後端.事實上,您可以自己定義後端.

因此,模型的所有更改都可能對資料庫產生影響.例如,您可以定義使用列的verbose_name作為“註釋字串”的後端,您經常可以在資料庫端新增到此列.如果您定義choices,那麼對於某些資料庫,後端可以嘗試在資料庫級別強制執行這些選擇.

因為,正如前面所說,Django的目的是不知道使用的後端,因此它的目的是保守,併為許多模型更改進行遷移.對於其中一些,後端將決定簡單地沒有做任何事情.所以沒有構建查詢,資料庫端沒有任何更改.您確實可以看到像“無用遷移”這樣的更改.但請記住,如果稍後使用不同的後端,這些“無用遷移”實際上可能會做一些事情.

由於此類遷移在資料庫方面沒有做任何事情,但這些通常不是時間共用.您可能希望檢視“squash”遷移檔案[Django-doc] ,從而減少使用的遷移檔案數量.遷移仍將是檔案的一部分,但由於沒有涉及任何查詢,它通常不會產生太大的傷害.

此外,實際上可以在欄位上修補deconstruct函式,這樣help_text等不再出現在deconstruct呼叫的結果中,因此“檢測器”不可見.這個 Gist指令碼顯示了修補makemigration命令的方法:

 """
Patch the creation of database migrations in Django
Import this early from `__init__.py``.
- Don't want verbose_name changes in the migrations file.
- Don't want help_text in the migrations file.
"""
from functools import wraps

from django.db.models import Field


def patch_deconstruct(old_func, condition):
    """
    Patch the ``Field.deconstruct`` to remove useless information.
    This only happens on internal apps, not third party apps.
    """

    @wraps(old_func)
    def new_deconstruct(self):
        name, path, args, kwargs = old_func(self)
        # AutoField has no model on creation, but can be skipped
        if hasattr(self, 'model') and condition(self):
            kwargs.pop('verbose_name', None)
            kwargs.pop('help_text', None)
        return name, path, args, kwargs
    return new_deconstruct


Field.deconstruct = patch_deconstruct(Field.deconstruct, lambda self: self.model.__module__.startswith('apps.'))
 

  相同標籤的其他問題

djangodjango-models