2011-12-23 16 views
5

Używam niestandardowego pola Django do reprezentowania JSON zakodowane dane:Zastosowanie forms.TextArea dla niestandardowego pola JSON w Django stronie administratora

class JSONField(models.TextField): 
    __metaclass__ = models.SubfieldBase 

    def to_python(self, value): 
     if value == "": 
      return None 

     try: 
      if isinstance(value, basestring): 
       return json_decode(value) 
     except ValueError: 
      pass 

     return value 

    def get_prep_value(self, value): 
     if value == "": 
      return None 
     if isinstance(value, dict) or isinstance(value, dict): 
      value = json_encode(value) 
      return super(JSONField, self).get_prep_value(value) 

    def value_to_string(self, obj): 
     value = self._get_val_from_obj(obj) 
     return self.get_db_prep_value(value,connection=None) 

Samo pole działa dobrze. Jednak edytowanie za pośrednictwem strony administratora nie jest możliwe, ponieważ ciąg z bazy danych jest dekodowany przez JSON i konwertowany na słownik, więc gdy strona administratora jest renderowana, nie jest wyświetlany rzeczywisty ciąg JSON z bazy danych (np. {"Foo": "bar"}), ale jego reprezentacja słownikowa (np. {u'foo ': u'bar'}).

Oczywiście prowadzi to do problemów podczas zapisywania obiektu bazy danych, ponieważ reprezentacja napisów słownika nie jest prawidłowym ciągiem JSON.

To, co chciałbym mieć to strona admin pokazująca rzeczywistą wartość bazy danych (tj. Ciąg znaków zapisany w bazie danych), zamiast reprezentacji łańcuchowej obiektu Pythona zwróconego przez to_python.

Moja próba polega na napisaniu niestandardowego widgetu, który po prostu wywołuje ponownie json_encode w słowniku - ale czy istnieje lepszy sposób?

Odpowiedz

4

value_from_object pomoże rozwiązać problem. Jego implementacja zależy od tego, który serializator został użyty, ale dla simplejson powinien wyglądać tak:

from django.utils import simplejson as json 
from django.core.serializers.json import DjangoJSONEncoder 

class JSONField(models.TextField): 
.... 

    def value_from_object(self, obj): 
     return json.dumps(super(JSONField, self).value_from_object(obj)) 
+0

Pomogło to. Dziękuję Ci bardzo! – ChrisM

Powiązane problemy