モデルクエリセットをシリアル化する方法に関するドキュメントはたくさんありますが、モデルインスタンスのフィールドをJSONにシリアル化するにはどうすればよいですか?
モデルクエリセットをシリアル化する方法に関するドキュメントはたくさんありますが、モデルインスタンスのフィールドをJSONにシリアル化するにはどうすればよいですか?
回答:
リストを使用して必要なオブジェクトをラップすることは簡単で、djangoシリアライザがそれを正しくシリアル化するために必要なことはすべてこれにあります。例:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
@DavorLucicが提案するように、最後の行の終わりにしたくないですか?また、リストリテラルの末尾にコンマを付ける必要はありません(PEP8が大好きなため;)。
モデルインスタンスのリストを処理する場合、使用できる最善の方法はを使用することでありserializers.serialize()
、ニーズに完全に適合します。
ただし、オブジェクトではなく単一のオブジェクトをシリアル化しようとすると、問題が発生しlist
ます。そうmodel_to_dict
すれば、さまざまなハックを取り除くために、Djangoを使用するだけです(私が間違っていない場合serializers.serialize()
は、それに依存しています)。
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
json.dumps
これで、jsonにシリアル化するための1つのストレートコールが必要になります。
import json
serialized = json.dumps(dict_obj)
それでおしまい!:)
datetime
フィールドで失敗します。json.loads(serialize('json', [obj]))[0]
シリアライザがいる間にこの方法で解決しましたdjango.core.serializers.serialize
配列ラッパーを回避するには、応答を返す前にそれを削除します。
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を使用しており、ジョブに最適なツールのように見えます。
これには良い答えがあり、言及されていないことに驚いています。数行で、日付、モデル、その他すべてを処理できます。
モデルを処理できるカスタムエンコーダーを作成します。
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)
これで、モデル、日付、およびすべてをシリアル化できるようになり、配列に入れたり、シリアル化してシリアル化したりする必要がなくなりました。あなたが持っているものはすべてカスタムに追加することができますdefault
メソッドにます。
DjangoのネイティブJsonResponseを次のように使用することもできます。
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
とjson.dump
メソッドの両方で使用できます。この方法では、jsonに変換する前にカスタムオブジェクトを使用するか、別のメソッド呼び出しを追加するため、アプリケーションのワークフローを変更する必要はありません。エンコーダーに変換コードを追加するだけで準備完了です。
相互運用性のために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
、データベース内の数値と文字列のみなど)がない限り、役に立ちません。それ以外の場合は、このメソッドを実装する正しい方法を真剣に検討する必要があります。
第三に、電話をかけdemjson.JSON.encode(instance)
、あなたはあなたが欲しいものを持っています。
モデルから単一のオブジェクトをシリアル化する方法を尋ねていて、クエリセットでオブジェクトを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?"}}
私はモデルにシリアル化メソッドを追加することでこの問題を解決しました:
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
インスタンスおよびモデル自体からアクセスできるモデルフィールドの順序付きリストです。
これが私の解決策です。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)
car.json()
リストを使用して、問題を解決します
ステップ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")
シリアル化および逆シリアル化するには、以下を使用します。
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
.values()
モデルインスタンスをJSONに変換するために必要なものです。
.values()のドキュメント: https
Projectというモデルでの使用例。
注:私はDjango Rest Frameworkを使用しています
@csrf_exempt
@api_view(["GET"])
def get_project(request):
id = request.query_params['id']
data = Project.objects.filter(id=id).values()
if len(data) == 0:
return JsonResponse(status=404, data={'message': 'Project with id {} not found.'.format(id)})
return JsonResponse(data[0])
有効なIDの結果:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
python
フォーマットで使用し、from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
とpython
形式の違いは何ですか?json
ような形式は、結果が返されstr
、一方python
で結果を返すのいずれかlist
、またはOrderedDict
OrderedDict
、ではなくdict
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
私はインスタンスの口述を返します
したがって、{'field1':value、 "field2":value、....}のようなものを返します
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
これらの答えはすべて、私がフレームワークから期待するもの、最も簡単な方法と比較して少しハックでした。私がはるかに、残りのフレームワークを使用していると思います。
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
これはシリアライザを直接使用し、それに定義したフィールドや関連などを尊重します。
django.core
これを行うためにクラスを使用することはできません。クエリセットのシリアル化を使用しない特別な理由はありますか?