Вывод сериализанных данных в json django
Я только начинаю изучать django. Подскажите, пожалуйста, как правильно вывести данные из разных таблиц, имеющих связь друг с другом, в persons_list используя метод сериализации данных (необходимо заменить id значениями LoanTypeParticipation и Name). Сейчас получаю следующий результат:
0: {Id_Incidents: 120, Id_Group: 13, Type_Participation: "p", Id_People: 2, Competencies: "есть"}
Serialize.py
from rest_framework import serializers
from .models import AkpGroup, AkpPeople
class GroupSerializer(serializers.ModelSerializer):
AkpGroups = serializers.StringRelatedField(many=True)
class Meta:
model = AkpGroup
fields = ['Id_Incidents', 'Type_Participation', 'AkpGroups', 'Competencies']
Views.py
def load_table(request):
error = ''
id_incidents = request.session.get('Id_Incidents', 'ничего не передано')
if request.method == "GET":
if request.user:
try:
persons = AkpGroup.objects.filter(Id_Incidents=120) # запрос в базу данных
except AkpGroup.objects.DoesNotExist:
persons = None
pers = persons.all().values('Id_Incidents', 'Id_Group', 'Type_Participation', 'Id_People', 'Competencies')
persons_list = list(pers)
return JsonResponse(persons_list, safe=False)
Models.py
class AkpPeople(models.Model):
Id_People = models.AutoField(primary_key=True, verbose_name='Идентификатор участника группы АКП')
Name = models.CharField(max_length=256, verbose_name='Ф.И.О.')
Post = models.CharField(max_length=256, verbose_name='Должность:')
objects = models.Manager()
def __str__(self):
# return self.Name
return '%s (%s)' % (self.Name, self.Post)
class Meta:
db_table = 'akp_people'
verbose_name = 'Участник группы АКП'
verbose_name_plural = 'Участники групп АКП'
class AkpGroup(models.Model):
Id_Group = models.AutoField(primary_key=True, verbose_name='Идентификатор участника группы АКП')
Id_Incidents = models.ForeignKey('AkpIncidents', models.DO_NOTHING, verbose_name='Идентификатор инцидента')
# stage 3 fields
Id_People = models.ForeignKey('AkpPeople', models.DO_NOTHING,
related_name='AkpGroups', verbose_name='Ф.И.О. участника')
Competencies = models.CharField(max_length=256, verbose_name='Компетенции')
LoanTypeParticipation = (
('d', 'Руководитель группы'),
('p', 'Член группы')
)
Type_Participation = models.CharField(max_length=1, choices=LoanTypeParticipation,
verbose_name='Тип участия')
# Вспомогательные
Change_Time = models.DateTimeField(auto_now=True, blank=True, null=True, verbose_name='Время изменения')
Change_User = models.CharField(max_length=256, blank=True, null=True, verbose_name='Пользователь, внесший изменения')
Del_Date = models.DateTimeField(auto_now=False, blank=True, null=True, verbose_name='Дата удаления')
Del_User = models.CharField(max_length=256, blank=True, null=True, verbose_name='Пользователь, удаливший данные')
Is_Delete = models.BooleanField(default=False, verbose_name='Удален')
Is_Posted = models.BooleanField(default=False, verbose_name='Опублековано')
objects = models.Manager()
def display_id_people(self):
"""
Creates a string for the Genre. This is required to display genre in Admin.
"""
return ', '.join([Id_People.Name for Id_People in self.Id_People.all()[:10]])
display_id_people.short_description = 'AkpGroup'
def __str__(self):
return self.Competencies
class Meta:
db_table = 'Akp_Group'
verbose_name = 'Группа АКП'
verbose_name_plural = 'Группы АКП'
Для решения задачи требовалось передать сериализованные данные модели AkpPeople по внешнему ключу модели AkpGroup.
Для решения использовал:
- Видеоурок: https://youtu.be/sxdPf3z6Uw8
- Пример реализации: https://github.com/TonikX/ITMO_ICT_WebDevelopment_Examples/tree/example-serializers/example_2310
Решение:
Serialize.py
from .models import *
from rest_framework import serializers
class PeopleSerializer(serializers.ModelSerializer):
class Meta:
model = AkpPeople
fields = ['Name', 'Post']
class FilialSerializer(serializers.ModelSerializer):
class Meta:
model = AkpFilial
fields = ['Name_Filial']
class DepartmentSerializer(serializers.ModelSerializer):
class Meta:
model = AkpDepartment
fields = ['Name_Department']
class GroupNestedSerializer(serializers.ModelSerializer):
# делаем наследование
Id_People = PeopleSerializer()
# уточняем поле
Type_Participation = serializers.CharField(source="get_Type_Participation_display", read_only=True)
class Meta:
model = AkpGroup
fields = ['Id_Incidents', 'Id_Group', 'Type_Participation', 'Id_People', 'Competencies']
class IncidentsSerializer(serializers.ModelSerializer):
groups = GroupNestedSerializer(many=True, read_only=True)
filial = FilialSerializer(source='Id_Filial')
department = DepartmentSerializer(source='Id_Department')
class Meta:
model = AkpIncidents
fields = ['Id_Incidents', 'Date', 'filial', 'department', 'Short_Description', 'groups']
Views.py
def load_table(request):
error = ''
id_incidents = request.session.get('Id_Incidents', 'ничего не передано')
if request.method == "GET":
if request.user:
try:
incidents = AkpIncidents.objects.get(Id_Incidents=id_incidents) # запрос в базу данных
except AkpIncidents.objects.DoesNotExist:
incidents = None
serializer = IncidentsSerializer(incidents, many=True)
return JsonResponse(serializer.data, safe=False)
else:
return HttpResponse(status=403)
else:
return HttpResponse(status=405)
Urls.py
app_name = "main"
urlpatterns = [
path('', views.start, name="start"),
path('incident', views.incident, name="incident"),
path('victim', views.victim, name="victim"),
path('group', views.Groups.as_view(), name='group'),
path('CheckResult', views.CheckResult.as_view(), name='CheckResult'),
path('AdditionalDetail', views.additional_detail, name='AdditionalDetail'),
path('events', views.events, name='events'),
path('monitoring', views.monitoring, name='monitoring'),
path(
'url_to_django/delete_person/<int:Id_Group>',
views.delete_person,
name='delete_person'),
path(
'url_to_django/add_person/',
views.add_person,
name='add_person'),
path(
'url_to_django/load_table/',
load_table,
name='load_table')
Дополнение:
Views.py
Для решения задачи было бы гораздо лучше расположить смежные функции внутри одного класса. Я только начал изучать Django, и пока не понял как обратиться непосредственно к конкретной функции, находящейся внутри класса.
class GroupListRelatedAPIView(generics.ListAPIView):
queryset = AkpIncidents.objects.filter(Id_Incidents=id_incidents)
serializer_class = IncidentsSerializer
def load_table(request):
*********
def delete_person(request, Id_Group):
*********
def add_person(request):
*********
Urls.py
app_name = "main"
urlpatterns = [
path(
'url_to_django/load_table/',
GroupListRelatedAPIView.as_view(),
name='load_table')