2013-01-17 12 views
7

Ich habe eine Tabelle in mysql, die den Typ TextField (Django) mit dem JSONField ist. Dies ist, wie mein ModellDjango (JSONField) und tastypie

from django.db import models 
from json_field import JSONField 

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

Der Wert I über tastypie senden ist

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

in der Datenbank sieht ich

{"data":"value"} 

Aber wenn retrive die Daten mit curl sehen kann ich etwas wie das

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

Was kann ich tun, um die python''field'-Repräsentation nicht in die Ausgabe des tastypie zu bringen?

danke!

+0

gefunden, was das Problem war - das Feld als Unicode aus der Datenbank wurde serialisiert und gesendet wurde, wie durch tastypie ist - es mir zu beheben Verwenden Sie die Hydrat-Methode auf der Ressource in 'laden' es als Python-Datenstruktur und senden Sie es an tastypie. – silviud

+3

Es wäre gut, wenn Sie den Code Ihrer Lösung in einer Antwort auf diese Frage teilen würden. Dann markieren Sie es bitte als die angenommene Antwort. –

Antwort

4

Ich reparierte dieses Problem wie folgt:

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

Mein JSONField user_inputs gestattet. Voraussetzung ist das Modell, zu dem es gehört.

Ich fühle mich komisch, eine Abfrage hier zu tun, wenn Tastypie dies bereits für mich getan hat, aber das funktioniert. Ich würde mich freuen, wenn es bessere Lösungen gäbe.

+5

Sie müssen die db-Abfrage nicht ausführen, da sich Ihr 'Requirement'-Objekt bereits in' bundle.obj' befindet. Sie können Ihre Lösung zu def dehydrate_user_inputs(self, bundle): return json.dumps(bundle.obj.user_inputs) tcmb

+1

@tcmb vereinfachen Ich glaube, dass Ihr Kommentar nicht korrekt ist (zumindest in tastypie 0.11.1). Zu der Zeit, wenn Sie zu Dehydrierung kommen, wurde das JSON-Objekt bereits in Unicode konvertiert (ich nehme an, dass es tastypie ist). Um dies zu beheben, müssen Sie es erneut lesen, wie kvnn sagt. Sehen Sie meine Antwort für einen anderen Ansatz (an den Punkt der Hydratation). –

1

Ich stieß auf ähnliche Probleme, wo meine Unicode-Strings in einem seltsamen Format in der API zurückgegeben würden (ich denke, die rohen codierten Strings wurden im Gegensatz zu den tatsächlichen utf-8 Zeichen zurückgegeben).

Wie auch immer, anstatt die dehydrierte Methode zu verwenden und die Abfrage erneut auszuführen, ist es besser, einen benutzerdefinierten Serializer in Ihren Ressourcen zu verwenden.

Dies ist, was ich verwendet:

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) 

dann in Ihre Ressourcen:

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

Verwendung DictField:

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

Geht zur Show, es lohnt sich immer, runterscrollen und sich die anderen Antworten auf StackOverflow anzusehen. Das war eine großartige Antwort. Ich habe 'obj = fields.ListField (attribute =' obj ') 'vorher benutzt, aber das war für Array-ähnliche Daten, das war genau das, was ich für mehr dict wie Daten brauchte. – teewuane

4

Der Fehler wird verursacht, sind zu sehen von Tastypie Behandlung das JSONField wie eine TextArea und das Aufrufen von str() für das Objekt, das JSONField vor der Rückgabe von i zurückgibt t an den Anrufer.

Ein anderer Ansatz ist die Verwendung von fields.ApiFields für das JSONField. Dies funktioniert, weil fields.ApiFields keine Konvertierungen durchführt, weder in (hydrate()) noch nach außen (convert()). Dies ist genau das, was wir wollen - das zugrunde liegende JSONField wird das JSON-Objekt in eine Zeichenfolge für die Persistenz auf dem Weg in konvertieren und das Objekt aus der Zeichenfolge auf dem Weg nach draußen neu erstellen. Tastypie muss also nichts tun. Mein Code sieht ein bisschen wie diese (Klasse/Variablennamen basierend auf OPs Beispiel) -

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

class MyModelResource(ModelResource): 
    obj = JSONField('obj') 
Verwandte Themen