2013-01-31 10 views
6

Używam Mongodb z mongoengine jako zaplecza dla API w Django. Ramy używane do tworzenia interfejsu API to Django Rest Framework.Django Rest Framework Dictionary Field

Potrzebuję przechowywać słownik w polu w Mongo, a najlepsze, co zrobiłem, gdy wywoływany jest post metody to użycie charfield i przeanalizowanie słownika w funkcji restore_object.

Jest lepszy sposób na osiągnięcie tego celu?

Lepiej jest utworzyć pole dyktowania? Nie wiem, jak trudne może to być.

Dziękuję.

edytowane, aby pokazać kod, zauważ, że przechowuję słownik jako dyktando (DictField), a jego treść może się zmieniać z jednego obiektu na inny.

mój model mongoengine jest coś takiego:

class MyDoc(mongoengine.Document): 
    name = mongoengine.StringField(max_length=200) 
    context = mongoengine.DictField() 

i mój serializatora coś takiego:

class MyDocSerializer(serializers.Serializer): 

name = serializers.CharField(max_length=200) 
context = serializers.CharField() 
url = serializers.HyperlinkedIdentityField(
view_name="drf:mydoc-detail",) 

def __init__(self,*args,**kwargs): 
    super(MyDocSerializer,self).__init__(*args,**kwargs) 


def restore_object(self, attrs, instance=None): 

    #Parse string to dict 
    #this is so ugly, notice I had to repace ' for " to 
    #avoid an error parsing the json 
    context = JSONParser().parse(
    StringIO.StringIO(
     attrs['context'].replace("'","\"") 
    ) 
    ) 

    attrs['context'] = context 
    if instance is not None: 
     instance.name = attrs['name'] 
     instance.context = context 
     return instance 

    return MyDoc(**attrs) 
+0

można zamieścić swoje definicje dokumentów i jakiś kod? Myślę, że byłoby pomocne – dm03514

+0

Możesz użyć serializatorów pymongo - patrz: http://api.mongodb.org/python/current/api/bson/json_util.html – Ross

+0

W 2016 roku możesz użyć Django-REST-Framework-Mongoengine (https://github.com/umutbozkurt/django-rest-framework-mongoengine), który zapewnia seryjne moduły do ​​dokumentów Mongoengine po wyjęciu z pudełka. –

Odpowiedz

6

Zamiast zajmować się pola słowniku w serializer na restore_object, będziesz prawdopodobnie skończyć z coś nieco czystszego, jeśli zamiast tego użyjesz pola niestandardowego dla pola słownika, które zarządza konwersją między reprezentacją słownika i pamięcią wewnętrzną.

Będziesz chciał podklasę serializers.WritableField i zastąpić metody to_native() i from_native.

Relevant docs here.


Uwaga: klasa WritableField, która była obecna w wersji 2.x już nie istnieje. Powinieneś podklasować Field i nadpisać to_internal_value(), jeśli pole obsługuje wprowadzanie danych.


Aktualizacja: Począwszy od wersji 3.0.4 można teraz używać serializers.DictField ... http://www.django-rest-framework.org/api-guide/fields/#dictfield