如何处理"SubfieldBase已被弃用.请改用Field.from_db_value."

mja*_*ews 15 django django-models

升级到Django 1.9后,我现在收到警告

RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead.
Run Code Online (Sandbox Code Playgroud)

我知道问题出在哪里.我有一些自定义字段定义,其中我有__metaclass__ = models.SubfieldBase.例如,

class DurationField(models.FloatField):

    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):

    ...
Run Code Online (Sandbox Code Playgroud)

如果该__metaclass__语句被弃用,我应该用什么来替换它呢?

我是否只是将其取出并添加一个from_db_value方法,如下例所示:https://docs.djangoproject.com/en/1.9/howto/custom-model-fields/#converting-values-to-python-objects

以及如何from_db_valueto_python不同?两者似乎都将数据库数据转换为Python对象?

ozr*_*983 32

是的,你应该删除__metaclass__行并添加from_db_value()to_python():

class DurationField(models.FloatField):

    def __init__(self, *args, **kwargs):
        ...

    def from_db_value(self, value, expression, connection, context):
        ...

    def to_python(self, value):
        ...
Run Code Online (Sandbox Code Playgroud)

如下所述:https://docs.djangoproject.com/en/1.9/ref/models/fields/#field-api-reference,to_python(value)将值(可以是None,string或object)转换为正确的Python对象.

from_db_value(value, expression, connection, context) 将数据库返回的值转换为Python对象.

因此,两种方法都返回Python对象,但Django在不同情况下使用它们.to_python()通过反序列化和clean()从表单中使用的方法调用.from_db_value()从数据库加载数据时调用

  • 这是非常好的和全面的答案。@mjandrews:你为什么不把它标记为最终答案? (2认同)

jbu*_*bub 5

虽然 ozren 是对的,但有一个巨大的差异,有SubfieldBase一个非常肮脏的副作用,它总是调用to_python给给定模型字段赋值的方法。我最近在从 Django 1.9 升级到 1.10 时遇到了这个问题。

看:

https://docs.djangoproject.com/en/2.1/releases/1.8/#subfieldbase

  • 另一个链接可能有帮助 https://docs.djangoproject.com/en/2.1/ref/models/fields/#django.db.models.Field.from_db_value (2认同)