web-dev-qa-db-ja.com

Djangoでモデルインスタンスをどのようにシリアル化しますか?

モデルQuerySetをシリアル化する方法に関するドキュメントは多数ありますが、モデルインスタンスのフィールドをJSONにシリアル化するにはどうすればよいですか?

136
Jason Christa

リストを簡単に使用して必要なオブジェクトをラップすることができます。これは、Djangoシリアライザーが正しくシリアル化するために必要なものです。たとえば:

from Django.core import serializers

# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
217
xaralis

モデルインスタンスのリストを処理する場合、serializers.serialize()を使用することが最善です。これは、ニーズに完全に適合します。

ただし、オブジェクトのlistではなく、singleオブジェクトをシリアル化しようとすると問題が発生します。そのようにして、さまざまなハックを取り除くために、Djangoのmodel_to_dictを使用します(私が間違っていなければ、serializers.serialize()もそれに依存しています)。

from Django.forms.models import model_to_dict

# assuming obj is your model instance
dict_obj = model_to_dict( obj )

Jsonにシリアル化するには、1つのjson.dumps呼び出しが必要です。

import json
serialized = json.dumps(dict_obj)

それでおしまい! :)

55
Pavel Daynyak

配列ラッパーを回避するには、応答を返す前にそれを削除します。

import json
from Django.core import serializers

def getObject(request, id):
    obj = MyModel.objects.get(pk=id)
    data = serializers.serialize('json', [obj,])
    struct = json.loads(data)
    data = json.dumps(struct[0])
    return HttpResponse(data, mimetype='application/json')

このテーマに関するこの興味深い投稿も見つけました。

http://timsaylor.com/convert-Django-model-instances-to-dictionaries

Django.forms.models.model_to_dictを使用します。これは、仕事に最適なツールのようです。

41
Julian

あなたが求めているのは、相互運用性のためにDjangoモデルインスタンスのデータ構造をシリアル化することです。他のポスターは正しいです:Djangoのapiを介してデータベースにクエリできるpythonアプリケーションでシリアル化されたフォームを使用したい場合は、1つのオブジェクトでクエリセットをシリアル化します。一方、データベースに触れずに、またはDjangoを使用せずに、モデルインスタンスを別の場所に再インフレートする方法が必要な場合は、少し作業が必要です。

ここに私がやることがあります:

まず、変換に demjson を使用します。たまたま私が最初に見つけたものですが、最高ではないかもしれません。私の実装はその機能の1つに依存しますが、他のコンバーターでも同様の方法があるはずです。

次に、シリアル化が必要なすべてのモデルにjson_equivalentメソッドを実装します。これはdemjsonの魔法のメソッドですが、どの実装を選択しても、おそらく考えたいことです。これは、jsonに直接変換可能なオブジェクト(つまり、配列または辞書)を返すという考え方です。本当にこれを自動的に行いたい場合:

def json_equivalent(self):
    dictionary = {}
    for field in self._meta.get_all_field_names()
        dictionary[field] = self.__getattribute__(field)
    return dictionary

これは、完全にフラットなデータ構造(ForeignKeysなし、データベース内の数字と文字列のみなど)がない限り、役に立ちません。そうでなければ、このメソッドを実装する正しい方法を真剣に考えるべきです。

3番目に、demjson.JSON.encode(instance)を呼び出すと、必要なものが得られます。

10
David Berger

モデルから単一のオブジェクトをシリアル化する方法を尋ねており、knowクエリセットで1つのオブジェクトのみを取得する場合(たとえば、objects.getを使用)、次のようなものを使用します:

import Django.core.serializers
import Django.http
import models

def jsonExample(request,poll_id):
    s = Django.core.serializers.serialize('json',[models.Poll.objects.get(id=poll_id)])
    # s is a string with [] around it, so strip them off
    o=s.strip("[]")
    return Django.http.HttpResponse(o, mimetype="application/json")

次のような形式になります:

{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
8
benlast

これには良い答えがあり、言及されていないことに驚いています。数行で、日付、モデル、その他すべてを処理できます。

モデルを処理できるカスタムエンコーダーを作成します。

from Django.forms import model_to_dict
from Django.core.serializers.json import DjangoJSONEncoder
from Django.db.models import Model

class ExtendedEncoder(DjangoJSONEncoder):

    def default(self, o):

        if isinstance(o, Model):
            return model_to_dict(o)

        return super().default(o)

Json.dumpsを使用するときに使用します

json.dumps(data, cls=ExtendedEncoder)

モデル、日付、およびすべてをシリアル化できるようになり、アレイにある必要も、シリアル化および非シリアル化する必要もありません。

7
kagronick

モデルにシリアル化メソッドを追加することで、この問題を解決しました。

def toJSON(self):
    import simplejson
    return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))

ワンライナーを嫌うこれらの冗長な同等物は次のとおりです。

def toJSON(self):
    fields = []
    for field in self._meta.fields:
        fields.append(field.name)

    d = {}
    for attr in fields:
        d[attr] = getattr(self, attr)

    import simplejson
    return simplejson.dumps(d)

_meta.fieldsは、インスタンスおよびモデル自体からアクセスできるモデルフィールドの順序付きリストです。

5
davidchambers

これに対する私のソリューションは、JSONを簡単にカスタマイズし、関連するレコードを整理できるようにすることです。

まず、モデルにメソッドを実装します。私はjsonと呼びますが、好きなように呼び出すことができます、例えば:

class Car(Model):
    ...
    def json(self):
        return {
            'manufacturer': self.manufacturer.name,
            'model': self.model,
            'colors': [color.json for color in self.colors.all()],
        }

次に、ビューで:

data = [car.json for car in Car.objects.all()]
return HttpResponse(json.dumps(data), content_type='application/json; charset=UTF-8', status=status)
5
DanH

リストを使用して、問題を解決します

ステップ1:

 result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();

ステップ2:

 result=list(result)  #after getting data from model convert result to list

ステップ3:

 return HttpResponse(json.dumps(result), content_type = "application/json")
4
niran

シリアライズおよびデシリアライズするには、次を使用します。

from Django.core import serializers

serial = serializers.serialize("json", [obj])
...
# .next() pulls the first object out of the generator
# .object retrieves Django object the object from the DeserializedObject
obj = next(serializers.deserialize("json", serial)).object
3
Zags

Django Serializer with python format、

from Django.core import serializers

qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)

jsonpython形式の違いは何ですか?

json形式は、strとして結果を返しますが、pythonは、listまたはOrderedDict

3
JPG

単一モデルオブジェクトjson応答としてクライアントに返す場合は、次の簡単な解決策を実行できます。

from Django.forms.models import model_to_dict
from Django.http import JsonResponse

movie = Movie.objects.get(pk=1)
return JsonResponse(model_to_dict(movie))
1
flowfelis

インスタンスをシリアル化できるとは思えません。1つのオブジェクトのQuerySetをシリアル化する必要があります。

from Django.core import serializers
from models import *

def getUser(request):
    return HttpResponse(json(Users.objects.filter(id=88)))

Djangoのsvnリリースを使い果たしたため、以前のバージョンにはない可能性があります。

1
Jack M.

この方法はどうですか:

def ins2dic(obj):
    SubDic = obj.__dict__
    del SubDic['id']
    del SubDic['_state']
return SubDic

不要なものを除外します。

1
Reorx
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......

return HttpResponse(simplejson.dumps(ville.__dict__))

インスタンスの辞書を返します

{'field1':value、 "field2":value、....}のようなものを返します

1
Jimmy