2012-06-15 63 views
0

我寫了一個自定義Django模型字段來存儲dateutil.relativedelta's。現場看起來是這樣的:嘗試將JSON序列化爲自定義Django模型字段時的TypeError

class RelativeDeltaField(models.CharField): 
    description = "Relative delta" 

    __metaclass__ = models.SubfieldBase 

    max_length = 200 

    def __init__(self, *args, **kwargs): 
     kwargs['max_length'] = self.max_length 
     super(RelativeDeltaField, self).__init__(*args, **kwargs) 

    def to_python(self, value): 
     if isinstance(value, relativedelta): 
      return value 

     try: 
      return eval(value) 
     except SyntaxError, e: 
      logging.error("Mangled data for a relativedelta field. Was the data truncated in MySQL column? Either manually fix, or change the next line to 'return None' and manually fix. value=%r message=%r" % (value, e)) 
      raise 

    def get_db_prep_save(self, value, connection): 

     return repr(value) 

    def value_to_string(self, obj): 
     value = self._get_val_from_obj(obj) 
     return self.get_prep_value(value) 

我想序列化的對象與此字段以JSON:

serializers.serialize('json', obj) 

但我得到一個錯誤:

… 
    File "/home/rory/tix/virtualenv/lib/python2.6/site-packages/django/core/serializers/json.py", line 58, in default 
    return super(DjangoJSONEncoder, self).default(o) 
    File "/usr/lib/python2.6/dist-packages/simplejson/encoder.py", line 190, in default 
    raise TypeError(repr(o) + " is not JSON serializable") 
TypeError: relativedelta(hours=+1) is not JSON serializable 

從使用pdb,我可以看到o在這種情況下是對象本身,它沒有被轉換爲任何東西,也沒有被序列化。

我該如何解決這個問題,這樣我才能連載我的領域?

Django文檔說(https://docs.djangoproject.com/en/dev/howto/custom-model-fields/#converting-field-data-for-serialization)添加value_to_string,我確實有。

+0

你到底想如何序列化它?你用什麼格式來表示'relativedeta(hours = + 1)'作爲一個字符串? –

+0

我希望JSON序列化程序與數據庫中的數據庫相同,它是值的''repr'',即它應該是字符串''「relativedelta(小時= + 1)」'' – Rory

回答

1

doc中的代碼只是樣板,您需要執行value_to_string以返回代表relativedelta的字符串。

RelativeDeltaField基於models.CharField,因此get_prep_value()看起來像

def get_prep_value(self, value): 
    return self.to_python(value) 

它是CharField OK,因爲在該領域的Python的預期值已經是一個字符串。但是,您的定製版本to_python()返回relativedelta而不是字符串。

+0

似乎是問題所在。不知道爲什麼我只使用get_db_prep_value – Rory

相關問題