Ada*_*evy 8 django field django-models
如何确保仅在从DB加载字段中的数据时调用自定义字段的*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)
Run Code Online (Sandbox Code Playgroud)
...当我在交互式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
Run Code Online (Sandbox Code Playgroud)
我以为我能做到这样的事......
>>> 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()
Run Code Online (Sandbox Code Playgroud)
...我究竟做错了什么?
TypeError只有在第一次为该字段赋值时才会得到 吗?你可以在它周围写一个 try/ except :
def to_python(self, value):
try:
return decode(value)
except TypeError:
return value
Run Code Online (Sandbox Code Playgroud)
这不是最干净的解决方案,但您可以尝试一下,看看它是否可以让您按照预期的方式处理该领域。
| 归档时间: |
|
| 查看次数: |
3077 次 |
| 最近记录: |