MySql 生成列的 Django 模型字段只读

Django Model field read only for a MySql generated column

我想将 generated column 添加到 MySql 数据库,我正在寻找一种方法来从 Django 模型对象中读取该列,但没有它 ever 尝试在 insert/update 上为该列写入一个值,而 MySql 将在该列上引发错误。

我知道您可以轻松地将管理站点表单上的字段设置为只读,但是有没有办法在 model/field 级别设置它?

您应该能够添加执行原始 SQL 查询的方法。

https://docs.djangoproject.com/en/2.2/topics/db/sql/

另一种选择是将默认管理器覆盖为 return QuerySet,它始终用该列的值进行注释:

from django.db.models.expressions import RawSQL

class MyManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().annotate(
            my_field=RawSQL('''"{table}"."myfield"'''.format(
                table=self.model._meta.db_table
            ), ())
        )

然后在您的模型中设置 objects = MyManager(),每当您获取对象时,它们都会用您想要的字段进行注释:

instance = MyModel.objects.first()
instance.my_field  # value from db annotation

还有一个选项:

def get_deferred_fields(self):
    deferred_fields = super(MyModel, self).get_deferred_fields()

    # Exclude MySQL generated columns, which cannot be saved
    deferred_fields.update({
        "my_generated_column_field1",
        "my_generated_column_field2",
    })

    return deferred_fields

注意:get_deferred_fields() 是一个 public 方法,它可以被覆盖,但可能会产生意想不到的副作用。在我的 Django 应用程序中,它仅在 save() 期间被调用,而在 refresh_from_db() 期间从未被调用,但它可以。