широко распространен в исходном коде django, и он называется везде как беспорядок. WTF, чтобы вызвать одну и ту же функцию в form-> db и db-> form? Кто это спроектировал?

могу гарантировать, что метод * to_python () * моего настраиваемого поля вызывается только тогда, когда данные в поле были загружены из БД?

Я пытаюсь использовать настраиваемое поле для обработки кодирования / декодирования Base64 одного свойства модели. Казалось, что все работает правильно, пока я не создал экземпляр нового экземпляра модели и не установил это свойство с его значением в виде открытого текста ... В этот момент Django попытался декодировать поле, но потерпел неудачу, потому что это был открытый текст.

Прелесть реализации пользовательского поля заключалась в том, что я думал, что смогу обработать 100% логики кодирования / декодирования, так что никакой другой части моего кода никогда не нужно было знать об этом. Что я делаю неправильно?

(ПРИМЕЧАНИЕ. Это всего лишь пример, иллюстрирующий мою проблему. Мне не нужны советы о том, как использовать или не использовать кодировку 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)

... и он ломается, когда я делаю это в интерактивной оболочке. Почему он вызывает to_python () здесь?

>>> 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

Я ожидал, что смогу сделать что-то вроде этого ...

>>> 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()

...Что я делаю неправильно?

Ответы на вопрос(1)

Ваш ответ на вопрос