Campo Customizado do Django: Execute apenas to_python () nos valores do DB?
Como garantir que o método * to_python () * do meu campo personalizado seja chamado apenas quando os dados no campo foram carregados do banco de dados?
Estou tentando usar um campo personalizado para manipular a codificação / decodificação Base64 de uma propriedade de modelo único. Tudo parecia estar funcionando corretamente até eu instanciar uma nova instância do modelo e definir essa propriedade com seu valor de texto sem formatação ... naquele momento, o Django tentou decodificar o campo, mas falhou porque era texto sem formatação.
O fascínio da implementação do campo personalizado era que eu pensava que poderia lidar com 100% da lógica de codificação / decodificação lá, para que nenhuma outra parte do meu código precisasse saber sobre isso. O que estou fazendo errado?
(NOTA: Este é apenas um exemplo para ilustrar meu problema, não preciso de conselhos sobre como devo ou não estar usando a Codificação Base64)
def encode(value):
return base64.b64encode(value)
def decode(value):
return base64.b64decode(value)
class EncodedField(models.CharField):
__metaclass__ = models.SubfieldBase
def __init__(self, max_length, *args, **kwargs):
super(EncodedField, self).__init__(*args, **kwargs)
def get_prep_value(self, value):
return encode(value)
def to_python(self, value):
return decode(value)
class Person(models.Model):
internal_id = EncodedField(max_length=32)
... e quebra quando faço isso no shell interativo. Por que está chamando to_python () aqui?
>>> from myapp.models import *
>>> Person(internal_id="foo")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.6/dist-packages/django/db/models/base.py", line 330, in __init__
setattr(self, field.attname, val)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/fields/subclassing.py", line 98, in __set__
obj.__dict__[self.field.name] = self.field.to_python(value)
File "../myapp/models.py", line 87, in to_python
return decode(value)
File "../myapp/models.py", line 74, in decode
return base64.b64decode(value)
File "/usr/lib/python2.6/base64.py", line 76, in b64decode
raise TypeError(msg)
TypeError: Incorrect padding
Eu esperava poder fazer algo assim ...
>>> from myapp.models import *
>>> obj = Person(internal_id="foo")
>>> obj.internal_id
'foo'
>>> obj.save()
>>> newObj = Person.objects.get(internal_id="foo")
>>> newObj.internal_id
'foo'
>>> newObj.internal_id = "bar"
>>> newObj.internal_id
'bar'
>>> newObj.save()
...O que estou fazendo errado?