如何確保只有在字段中的數據已從數據庫加載時才調用自定義字段的* to_python()*方法?Django自定義字段:只從數據庫的值運行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)
...和它打破當我在交互式shell中執行此操作時。爲什麼在這裏調用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()
......我究竟做錯了什麼?
是的,這也發生在我身上......我希望有一個更清潔的解決方案。我對Django一般都很陌生,特別是這是我第一次使用自定義字段,所以我的假設是要麼在我的自定義字段的聲明中丟失了某些內容,要麼有一個完全不同的,更合適的滿足我的需求。 – 2010-12-22 15:14:41
原來,這實際上是我能找到的唯一解決方案。失望的是沒有更好的方法來做到這一點。 – 2010-12-24 20:40:29
如果您存儲的數據恰好是有效的Base64輸入(例如`b'abcd'`),則這將失敗。然後不會產生TypeError,結果是錯誤的。 – 2011-08-09 00:20:53