2016-02-02 12 views
10

On aggiornamento a Django 1.9, io ora ottenere l'avvertimentoCome gestire "SubfieldBase è stato dichiarato obsoleto. Utilizza invece Field.from_db_value."

RemovedInDjango110Warning: SubfieldBase has been deprecated. Use Field.from_db_value instead. 

vedo dove si pone il problema. Ho alcune definizioni di campo personalizzate e in esse ho __metaclass__ = models.SubfieldBase. Ad esempio,

class DurationField(models.FloatField): 

    __metaclass__ = models.SubfieldBase 

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

    ... 

Se l'istruzione __metaclass__ è deprecato, cosa dovrei sostituirlo con esattamente?

Devo solo estrarlo e aggiungere un metodo from_db_value come nell'esempio qui: https://docs.djangoproject.com/en/1.9/howto/custom-model-fields/#converting-values-to-python-objects ?

E come sono diversi from_db_value e to_python? Entrambi sembrano convertire i dati del database in oggetti Python?

risposta

23

Sì, si dovrebbe semplicemente rimuovere __metaclass__ linea e aggiungere from_db_value() e 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): 
     ... 

Come descritto qui: https://docs.djangoproject.com/en/1.9/ref/models/fields/#field-api-reference, to_python(value) converte il valore (può essere None, stringa o oggetto) in oggetto Python corretta.

from_db_value(value, expression, connection, context) converte un valore restituito dal database a un oggetto Python.

Quindi, entrambi i metodi restituiscono oggetti Python, ma sono utilizzati da Django in diverse situazioni. to_python() viene chiamato dalla deserializzazione e durante il metodo clean() utilizzato dai moduli. from_db_value() viene chiamato quando i dati vengono caricati dal database

+1

questa è una risposta molto buona e completa. @mjandrews: perché non l'hai contrassegnato come una risposta finale? – pt12lol

+0

Ho scoperto che senza metaclasse, 'to_python' non è sempre chiamato lo stesso. Ad esempio, se crei una nuova istanza di un oggetto e poi provi a leggere il campo personalizzato, non chiamerà i metodi con cui il metaclass ha chiamato il metodo. –

Problemi correlati