Istnieje wiele dokumentacji na temat serializacji modelu QuerySet, ale jak po prostu serializować do JSON pola wystąpienia modelu?
Istnieje wiele dokumentacji na temat serializacji modelu QuerySet, ale jak po prostu serializować do JSON pola wystąpienia modelu?
Odpowiedzi:
Możesz łatwo użyć listy do zawijania wymaganego obiektu i to wszystko, czego serializatory django potrzebują, aby go poprawnie serializować, np .:
from django.core import serializers
# assuming obj is a model instance
serialized_obj = serializers.serialize('json', [ obj, ])
[0]
na końcu swojej ostatniej linii, jak zasugerował @DavorLucic? I nie ma potrzeby umieszczania przecinka na końcu listy dosłownie (z miłości do PEP8;).
Jeśli masz do czynienia z listą instancji modelu, najlepsze, co możesz zrobić, to użyć serializers.serialize()
, będzie idealnie pasować do twoich potrzeb.
Jednak napotkasz problem z próbą serializacji pojedynczego obiektu, a nie list
obiektów. W ten sposób, aby pozbyć się różnych hacków, po prostu użyj Django model_to_dict
(jeśli się nie mylę, też serializers.serialize()
na tym polega):
from django.forms.models import model_to_dict
# assuming obj is your model instance
dict_obj = model_to_dict( obj )
Teraz potrzebujesz tylko jednego bezpośredniego json.dumps
wywołania, aby serializować go do json:
import json
serialized = json.dumps(dict_obj)
Otóż to! :)
datetime
polami. Rozwiązałem to w ten sposób, json.loads(serialize('json', [obj]))[0]
podczas gdy serializator jestdjango.core.serializers.serialize
Aby uniknąć otoki tablicy, usuń ją przed zwróceniem odpowiedzi:
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')
Znalazłem też interesujący wpis na ten temat:
http://timsaylor.com/convert-django-model-instances-to-dictionaries
Używa django.forms.models.model_to_dict, które wygląda na idealne narzędzie do pracy.
Jest na to dobra odpowiedź i jestem zaskoczony, że nie została o tym wspomniana. Za pomocą kilku wierszy możesz obsłużyć daty, modele i wszystko inne.
Utwórz niestandardowy koder, który obsługuje modele:
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)
Teraz użyj go, gdy używasz json.dumps
json.dumps(data, cls=ExtendedEncoder)
Teraz modele, daty i wszystko to można serializować i nie musi to być w tablicy ani serializowane i nieserializowane. Wszystko, co masz niestandardowe, można po prostu dodać dodefault
metody.
Możesz nawet użyć natywnej JsonResponse Django w ten sposób:
from django.http import JsonResponse
JsonResponse(data, encoder=ExtendedEncoder)
``
json.dumps
i json.dump
. W ten sposób nie musisz zmieniać przepływu pracy aplikacji, ponieważ używasz niestandardowych obiektów lub dodajesz inne wywołanie metody przed konwersją na json. Po prostu dodaj swój kod konwersji w koderze i gotowe.
Wygląda na to, że pytasz o serializowanie struktury danych instancji modelu Django w celu zapewnienia współdziałania. Inne plakaty są poprawne: jeśli chcesz, aby serializowany formularz był używany z aplikacją Pythona, która może wysyłać zapytania do bazy danych za pośrednictwem interfejsu API Django, chciałbyś serializować zestaw zapytań za pomocą jednego obiektu. Jeśli z drugiej strony potrzebujesz sposobu na ponowne napełnienie instancji modelu w innym miejscu bez dotykania bazy danych lub bez użycia Django, to masz trochę pracy do wykonania.
Oto co robię:
Najpierw używam demjson
do konwersji. Tak się złożyło, że znalazłem to, co znalazłem jako pierwsze, ale może nie być najlepsze. Moja implementacja zależy od jednej z jego funkcji, ale powinny być podobne sposoby z innymi konwerterami.
Po drugie, zaimplementuj json_equivalent
metodę we wszystkich modelach, które mogą być potrzebne do serializacji. Jest to magiczna metoda demjson
, ale prawdopodobnie będzie to coś, o czym będziesz chciał pomyśleć bez względu na wybraną implementację. Chodzi o to, że zwracasz obiekt, który jest bezpośrednio konwertowany na json
(tj. Tablicę lub słownik). Jeśli naprawdę chcesz to zrobić automatycznie:
def json_equivalent(self):
dictionary = {}
for field in self._meta.get_all_field_names()
dictionary[field] = self.__getattribute__(field)
return dictionary
Nie będzie to pomocne, chyba że masz całkowicie płaską strukturę danych (nie ForeignKeys
, tylko liczby i ciągi znaków w bazie danych itp.). W przeciwnym razie powinieneś poważnie pomyśleć o właściwym sposobie wdrożenia tej metody.
Po trzecie, zadzwoń demjson.JSON.encode(instance)
i masz to, czego chcesz.
Jeśli pytasz, jak serializować pojedynczy obiekt z modelu i wiesz , że dostaniesz tylko jeden obiekt w zestawie zapytań (na przykład za pomocą objects.get), użyj czegoś takiego:
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")
co dałoby ci coś w formie:
{"pk": 1, "model": "polls.poll", "fields": {"pub_date": "2013-06-27T02:29:38.284Z", "question": "What's up?"}}
Rozwiązałem ten problem, dodając metodę serializacji do mojego modelu:
def toJSON(self):
import simplejson
return simplejson.dumps(dict([(attr, getattr(self, attr)) for attr in [f.name for f in self._meta.fields]]))
Oto rozwlekły odpowiednik dla tych, którzy mają awersję do jednowierszowych:
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
to uporządkowana lista pól modelu, do których można uzyskać dostęp z instancji oraz z samego modelu.
Oto moje rozwiązanie, które pozwala łatwo dostosować JSON, a także organizować powiązane rekordy
Najpierw zaimplementuj metodę na modelu. Dzwonię, json
ale możesz to nazwać, jak chcesz, np:
class Car(Model):
...
def json(self):
return {
'manufacturer': self.manufacturer.name,
'model': self.model,
'colors': [color.json for color in self.colors.all()],
}
Następnie w widoku robię:
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()
Użyj listy, to rozwiąże problem
Krok 1:
result=YOUR_MODELE_NAME.objects.values('PROP1','PROP2').all();
Krok 2:
result=list(result) #after getting data from model convert result to list
Krok 3:
return HttpResponse(json.dumps(result), content_type = "application/json")
Aby serializować i deserialze, użyj następującego:
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()
jest tym, czego potrzebowałem, aby przekonwertować instancję modelu na JSON.
Dokumentacja .values (): https://docs.djangoproject.com/en/3.0/ref/models/querysets/#values
Przykładowe użycie z modelem o nazwie Project .
Uwaga: używam 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])
Wynik z prawidłowego identyfikatora:
{
"id": 47,
"title": "Project Name",
"description": "",
"created_at": "2020-01-21T18:13:49.693Z",
}
python
formatem,from django.core import serializers
qs = SomeModel.objects.all()
serialized_obj = serializers.serialize('python', qs)
json
ipython
formatem ?json
Format zwróci wynik jako str
natomiast python
zwróci wynik w jednej list
lubOrderedDict
OrderedDict
, niedict
Wydaje się, że nie można serializować instancji, musiałbyś serializować QuerySet jednego obiektu.
from django.core import serializers
from models import *
def getUser(request):
return HttpResponse(json(Users.objects.filter(id=88)))
Skończyło mi się svn
wydanie django, więc może nie być we wcześniejszych wersjach.
ville = UneVille.objects.get(nom='lihlihlihlih')
....
blablablab
.......
return HttpResponse(simplejson.dumps(ville.__dict__))
Zwracam dyktando mojej instancji
więc zwraca coś takiego jak {'pole1': wartość, "pole2": wartość, ....}
TypeError: <django.db.models.base.ModelState object at 0x7f2b3bf62310> is not JSON serializable
Wszystkie te odpowiedzi były trochę zepsute w porównaniu z tym, czego oczekiwałbym od frameworka, myślę, że najprostsza metoda, jeśli używasz reszty:
rep = YourSerializerClass().to_representation(your_instance)
json.dumps(rep)
Używa to Serializatora bezpośrednio, z poszanowaniem pól, które zdefiniowałeś w nim, a także wszelkich skojarzeń itp.
django.core
. Czy jest jakiś szczególny powód, aby nie używać serializacji zestawu zapytań?