2013-01-17 17 views
7

Ho una tabella in mysql che è il tipo TextField (django) usando JSONField. Ecco come il mio modello sembraDjango (JSONField) e tastypie

from django.db import models 
from json_field import JSONField 

class Model(models.Model): 
    obj  = JSONField() 

Il valore mando via tastypie è

json_string = '{"data":"value"}' 

nel database posso vedere

{"data":"value"} 

Ma quando retrive i dati con l'arricciatura ottengo qualcosa di simile

"{u'data': u'value'}" 

Cosa posso fare per non avere la rappresentazione di python u'field nell'output del tastypie?

grazie!

+0

trovi quello fosse il problema - il campo è stato serializzato come unicode dal database e fu inviato come è da tastypie - per risolvere il problema ho usato il metodo hydrate sulla risorsa in 'load' come una struttura dati python e invialo a tastypie. – silviud

+3

Sarebbe bene se tu condividessi il codice della tua soluzione in una risposta a questa domanda. Quindi contrassegnarlo come risposta accettata. –

risposta

4

Ho risolto questo problema in questo modo:

def dehydrate_user_inputs(self, bundle): 
    requirement = Requirement.objects.get(pk = bundle.obj.pk) 
    user_inputs = json.dumps(requirement.user_inputs) 
    return user_inputs 

mio JSONField si chiama user_inputs. Il requisito è il modello a cui appartiene.

Mi sento strano fare una query qui quando Tastypie lo ha già fatto per me, ma funziona. Mi piacerebbe se ci fossero soluzioni migliori.

+5

Non è necessario eseguire la query db, poiché l'oggetto 'Requisito' è già in' bundle.obj'. Puoi semplificare la tua soluzione a def dehydrate_user_inputs(self, bundle): return json.dumps(bundle.obj.user_inputs) tcmb

+1

@ tcmb Credo che il tuo commento non sia corretto (almeno in tastypie 0.11.1). Quando si arriva alla disidratazione, l'oggetto JSON è già stato convertito in unicode (presumo per tastypie). Quindi, per risolvere questo problema al punto di disidratazione, è necessario rileggerlo come dice kvnn. Vedi la mia risposta per un altro approccio (affrontandolo al punto di idratazione). –

1

Ero in esecuzione in problemi simili in cui le mie stringhe Unicode sarebbero state restituite in un formato strano nell'API (penso che le stringhe codificate non elaborate siano state restituite in contrasto con i caratteri utf-8 effettivi).

Ad ogni modo invece di utilizzare il metodo di disidratazione e rifare la query, è meglio utilizzare un serializzatore personalizzato nelle risorse.

Questo è quello che ho usato:

class JSONSerializer(Serializer): 
    '''using the standard json library for better unicode support, 
     also note django.utils.simplejson, used in the standard Tastypie serializer, 
     is set for depreciation''' 

    def to_json(self, data, options=None): 
     options = options or {} 
     data = self.to_simple(data, options) 
     return json.dumps(data) 

poi nelle vostre risorse:

class PlaceResource(ModelResource): 
    class Meta: 
     queryset = Place.objects.all() 
     resource_name = 'place' 
     serializer = JSONSerializer() 
1

Uso DictField:

obj = fields.DictField(attribute='obj') 
+0

Va a mostrare, vale sempre la pena scorrere verso il basso e guardare le altre risposte su StackOverflow. Questa è stata una grande risposta. Ho usato 'obj = fields.ListField (attribute = 'obj')' prima, ma quello era per dati come array, questo era esattamente quello di cui avevo bisogno per dati più simili a dict. – teewuane

4

L'errore che stai vedendo è causato da Tastypie trattamento il JSONField come un TextArea e chiamando str() sull'oggetto JSONField restituisce prima di restituire i t al chiamante.

Un altro approccio consiste nell'utilizzare i campi.ApiFields per JSONField. Questo funziona perché fields.ApiFields non esegue conversioni né in modo (hydrate()) o wayout (convert()). Questo è esattamente ciò che vogliamo: il JSONField sottostante convertirà l'oggetto JSON in una stringa per la persistenza in entrata e ricrea l'oggetto dalla stringa in uscita. Quindi, tastypie non ha bisogno di fare nulla. Il mio codice sembra un po 'come questo (classe nomi/variabili in base a esempio di OP) -

class JSONField(fields.apiField): 
    """ Wrapper over fields.apiField to make what we're doing here clear """ 
    pass 

class MyModelResource(ModelResource): 
    obj = JSONField('obj') 
Problemi correlati