Django Преобразовать объект модели c вложенными объектами в JSON
Всем доброго времени суток :)
Передо мной стоит задача написать json-rpc api для общения двух django приложений. Для этого я нашел библиотеку(damn-simple-jsonprc-server, damn-simple-jsonprc-server-django) которая позволяет создавать jsonrpc методы, метод в качестве результата должен возвращать json либо объект который он сам сможет сериализовать в json, например список или словарь. После того как я передам объект в json я планирую его развернуть обратно в объект, чтобы затем передать в шаблон по ключу. Пробовал использовать select_related и prefetch_related, они никак не изменяют вид полученyого queryset
Соответственно я хочу в первом приложении запросить объект класса Form из БД(у меня postgres в docker контейнере если кому-то важно) и передать этот объект через json. Проблема состоит в том что запросив этот объект и преобразовав его к словарю с помощью метода model_to_dict из django.forms.model я получаю словарь вот такого вида:
{'id': 9, 'code': '0Gv16Kfal85ErlQv0viRZ0DFRH034l', 'questions': [<Questions: Questions object (26)>, <Questions: Questions object (27)>, <Questions: Questions object (28)>]}
где в поле questions хранятся объекты связанной модели (ManyToMany) Questions, которая в свою очередь имеет связанное поле choices. Как развернуть все эти вложенные объекты внутри одного словаря? То есть чтобы вместо Question object(26) у меня был словарь вида (и в нем еще попутно развернуть объекты choices):
{'id': 26, 'question': 'Введите ваше имя', 'question_type': 'short', 'required': True, 'answer_key': '', 'score': 0, 'feedback': None, 'choices': [<Choices: Choices object (26)>]}
Вот такая функция для получения формы из базы(сейчас она возвращает json полученный из queryset, состоящего из одного объекта формы, для queryset есть встроенный в django сериализатор, он questions переделывает вот в такой список "questions": [26, 27, 28])
часть файла views.py в которой объявлен метод jsnorpc
import jsonrpcserver as rpc
formcreator = rpc.Service()
@formcreator.method('viewform', takes_http_request=True)
def view_form_json(request, code):
formInfo = Form.objects.filter(code = code)
formInfo1 = Form.objects.get(code=code)
print(model_to_dict(formInfo1,'id,code,questions'))
print(serializers.serialize('json',formInfo))
result = serializers.serialize('json',formInfo)
formInfoObject = Form.objects.get(code=code)
print(list(formInfo.questions.all()))
for item in list(formInfoObject.questions.all()):
print(model_to_dict(item))
# formInfo1 = Form.objects.get(code = code)
# print(formInfo1.questions.all())
# for item in list(formInfo1.questions.all()):
# print(model_to_dict(Questions.objects.get(id=item.id)), end=' ')
# for items in list(item.choices.all()):
# print(model_to_dict(Choices.objects.get(id=items.id)))
#Checking if form exists
if formInfo.count() == 0:
return HttpResponseRedirect(reverse('404'))
else: formInfo = formInfo[0]
if formInfo.authenticated_responder:
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse("login"))
#print(dict(model_to_dict(formInfo)))
return result
часть файла urls.py, чтобы api работало
import jsonrpcdjango
urlpatterns = [
path('api/jsonrpc/', jsonrpcdjango.serve, kwargs={'service': formcreator}),
]
Вот так хочу использовать объект который получу из json
render(request, "index/view_form.html", {
"form": formInfo
})
развернуть json в объект назад хочу вот так
formInfo = Form(**data_dict)
У меня есть такие модели в БД: (файл models.py)
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser, models.Model):
email = models.EmailField(unique=True)
class Choices(models.Model):
choice = models.CharField(max_length=5000)
is_answer = models.BooleanField(default=False)
class Questions(models.Model):
question = models.CharField(max_length=10000)
question_type = models.CharField(max_length=20)
required = models.BooleanField(default=False)
answer_key = models.CharField(max_length=5000, blank=True)
score = models.IntegerField(blank=True, default=0)
feedback = models.CharField(max_length=5000, null=True)
choices = models.ManyToManyField(Choices, related_name="choices")
class Answer(models.Model):
answer = models.CharField(max_length=5000)
answer_to = models.ForeignKey(Questions, on_delete=models.CASCADE, related_name="answer_to")
class Form(models.Model):
code = models.CharField(max_length=30)
title = models.CharField(max_length=200)
description = models.CharField(max_length=10000, blank=True)
creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="creator")
background_color = models.CharField(max_length=20, default="#d9efed")
text_color = models.CharField(max_length=20, default="#272124")
collect_email = models.BooleanField(default=False)
authenticated_responder = models.BooleanField(default=False)
edit_after_submit = models.BooleanField(default=False)
confirmation_message = models.CharField(max_length=10000, default="Ваш ответ был записан.")
is_quiz = models.BooleanField(default=False)
allow_view_score = models.BooleanField(default=True)
createdAt = models.DateTimeField(auto_now_add=True)
updatedAt = models.DateTimeField(auto_now=True)
questions = models.ManyToManyField(Questions, related_name="questions")
class Responses(models.Model):
response_code = models.CharField(max_length=20)
response_to = models.ForeignKey(Form, on_delete=models.CASCADE, related_name="response_to")
responder_ip = models.CharField(max_length=30)
responder = models.ForeignKey(User, on_delete=models.CASCADE, related_name="responder", blank=True, null=True)
responder_email = models.EmailField(blank=True)
response = models.ManyToManyField(Answer, related_name="response")