Ada banyak dokumentasi tentang cara membuat serialisasi Model QuerySet tetapi bagaimana Anda hanya membuat serial ke JSON bidang-bidang Model Instance?
Ada banyak dokumentasi tentang cara membuat serialisasi Model QuerySet tetapi bagaimana Anda hanya membuat serial ke JSON bidang-bidang Model Instance?
Jawaban:
Anda dapat dengan mudah menggunakan daftar untuk membungkus objek yang diperlukan dan itu semua yang diperlukan serializer django untuk membuat serialisasi dengan benar, misalnya .:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
di akhir baris terakhir Anda, seperti yang disarankan @DavorLucic? Dan tidak perlu untuk mengikuti koma dalam daftar Anda secara literal (untuk cinta PEP8;).
Jika Anda berurusan dengan daftar contoh model yang terbaik yang dapat Anda lakukan adalah menggunakannya serializers.serialize()
, itu akan sesuai dengan kebutuhan Anda dengan sempurna.
Namun, Anda harus menghadapi masalah dengan mencoba membuat serialisasi objek tunggal , bukan list
objek. Dengan begitu, untuk menyingkirkan hack yang berbeda, gunakan saja Django model_to_dict
(jika saya tidak salah, serializers.serialize()
andalkan juga):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Anda sekarang hanya perlu satu json.dumps
panggilan langsung untuk membuat serial menjadi json:
import json
serialized = json.dumps(dict_obj)
Itu dia! :)
datetime
bidang. Dipecahkan dengan cara ini json.loads(serialize('json', [obj]))[0]
sementara serializer adalahdjango.core.serializers.serialize
Untuk menghindari pembungkus array, hapus sebelum Anda mengembalikan respons:
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')
Saya menemukan posting yang menarik ini pada subjek juga:
http://timsaylor.com/convert-django-model-inances-to-dictionaries
Ini menggunakan django.forms.models.model_to_dict, yang terlihat seperti alat yang sempurna untuk pekerjaan itu.
Ada jawaban yang bagus untuk ini dan saya terkejut belum disebutkan. Dengan beberapa baris Anda dapat menangani tanggal, model, dan yang lainnya.
Buat pembuat enkode khusus yang dapat menangani model:
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)
Sekarang gunakan saat Anda menggunakan json.dumps
json.dumps(data, cls=ExtendedEncoder)
Sekarang model, tanggal dan semuanya dapat diserialisasi dan tidak harus dalam array atau serial dan tidak di-serial. Apa pun yang Anda miliki yang dapat ditambahkan hanya dapat ditambahkan kedefault
metode.
Anda bahkan dapat menggunakan JsonResponse asli Django dengan cara ini:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
dan keduanya json.dump
. Dengan cara ini Anda tidak perlu mengubah alur kerja aplikasi karena Anda menggunakan objek khusus atau menambahkan pemanggilan metode lain sebelum mengonversi ke json. Cukup tambahkan kode konversi Anda di enkoder dan Anda siap berangkat.
Kedengarannya seperti apa yang Anda tanyakan melibatkan serialisasi struktur data model Django misalnya untuk interoperabilitas. Poster-poster lain benar: jika Anda ingin formulir berseri untuk digunakan dengan aplikasi python yang dapat meminta basis data melalui api Django, maka Anda akan ingin membuat cerita bersambung sebuah queryset dengan satu objek. Jika, di sisi lain, apa yang Anda butuhkan adalah cara untuk kembali mengembang contoh model di tempat lain tanpa menyentuh database atau tanpa menggunakan Django, maka Anda memiliki sedikit pekerjaan yang harus dilakukan.
Inilah yang saya lakukan:
Pertama, saya gunakan demjson
untuk konversi. Kebetulan itulah yang saya temukan pertama kali, tetapi mungkin bukan yang terbaik. Implementasi saya tergantung pada salah satu fiturnya, tetapi harus ada cara yang serupa dengan konverter lainnya.
Kedua, terapkan json_equivalent
metode pada semua model yang mungkin Anda perlukan serial. Ini adalah metode ajaib demjson
, tetapi ini mungkin sesuatu yang ingin Anda pikirkan terlepas dari penerapan apa yang Anda pilih. Idenya adalah Anda mengembalikan objek yang dapat langsung dikonversi json
(yaitu array atau kamus). Jika Anda benar-benar ingin melakukan ini secara otomatis:
def json_equivalent(self):
dictionary = {}
for field in self._meta.get_all_field_names()
dictionary[field] = self.__getattribute__(field)
return dictionary
Ini tidak akan membantu Anda kecuali Anda memiliki struktur data yang benar-benar datar (tidak ForeignKeys
, hanya angka dan string dalam database, dll.). Jika tidak, Anda harus dengan serius memikirkan cara yang tepat untuk menerapkan metode ini.
Ketiga, telepon demjson.JSON.encode(instance)
dan Anda memiliki apa yang Anda inginkan.
Jika Anda bertanya bagaimana membuat serial objek tunggal dari model dan Anda tahu Anda hanya akan mendapatkan satu objek di queryset (misalnya, menggunakan objek.get), kemudian gunakan sesuatu seperti:
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")
yang akan memberi Anda sesuatu berupa:
{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
Saya memecahkan masalah ini dengan menambahkan metode serialisasi ke model saya:
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Berikut ini adalah padanan verbose bagi mereka yang menolak untuk satu kalimat:
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
adalah daftar bidang model yang dipesan yang dapat diakses dari instance dan dari model itu sendiri.
Inilah solusi saya untuk ini, yang memungkinkan Anda untuk dengan mudah menyesuaikan JSON serta mengatur catatan terkait
Pertama menerapkan metode pada model. Saya menelepon json
tetapi Anda bisa menyebutnya apa pun yang Anda suka, misalnya:
class Car(Model):
...
def json(self):
return {
'manufacturer': self.manufacturer.name,
'model': self.model,
'colors': [color.json for color in self.colors.all()],
}
Maka dalam tampilan saya lakukan:
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()
Gunakan daftar, itu akan menyelesaikan masalah
Langkah 1:
result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();
Langkah 2:
result=list(result) #after getting data from model convert result to list
Step3:
return HttpResponse(json.dumps(result), content_type = "application/json")
Untuk membuat serial dan deserialze, gunakan yang berikut ini:
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()
adalah apa yang saya butuhkan untuk mengonversi contoh model ke JSON.
dokumentasi .values (): https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
Contoh penggunaan dengan model yang disebut Project .
Catatan: Saya menggunakan 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])
Hasil dari id yang valid:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
python
format,from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
danpython
format?The json
Format akan kembali hasil sebagai str
sedangkan python
akan kembali hasilnya baik list
atauOrderedDict
OrderedDict
, tidakdict
Tampaknya Anda tidak bisa membuat serial suatu instance, Anda harus membuat serial suatu QuerySet dari satu objek.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
Saya kehabisan svn
rilis Django, jadi ini mungkin tidak ada di versi sebelumnya.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Saya kembalikan contoh saya
jadi itu mengembalikan sesuatu seperti {'field1': value, "field2": value, ....}
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Semua jawaban ini sedikit berantakan dibandingkan dengan apa yang saya harapkan dari suatu kerangka kerja, metode paling sederhana, saya pikir sejauh ini, jika Anda menggunakan kerangka kerja sisanya:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Ini menggunakan Serializer secara langsung, menghormati bidang yang telah Anda tentukan, serta asosiasi apa pun, dll.
django.core
untuk melakukan ini. Ada alasan khusus untuk tidak menggunakan serialisasi queryset?