Существует четыре модели:
class ObjectDataAdditional(models.Model):
#various fields and:
normal = models.ForeignKey(
'ObjectDataNormalized',
on_delete=models.CASCADE,
null=True,
related_name='additional_normal'
)
class ObjectDataNormalized(models.Model):
#various fields
class LinkedData(models.Model):
many = models.ManyToManyField(
ObjectDataNormalized,
related_name='many_related',
)
def __str__(self):
return u', '.join([str(a.pk) for a in self.many.all()])
class LinkedInfo(models.Model):
linked_data = models.ForeignKey(
LinkedData,
on_delete=models.CASCADE,
related_name='linked_data_related'
)
normalized = models.ForeignKey(
ObjectDataNormalized,
on_delete=models.CASCADE,
related_name='normalized_related'
)
main = models.BooleanField(
default=False,
null=False,
)
Здесь я получаю нужные мне данные:
info = LinkedInfo.objects.all().order_by('linked_data_id',
'-main').select_related(
'linked_data',
'normalized',
).prefetch_related(
'normalized__normal_object',
'normalized__additional_normal'
).annotate(max_percentage=Max(
'normalized__normal_object__additional_object__percentage_technical_readiness'))
final_data = []
temp_data = []
if info:
last_link_pk = info[0].linked_data.pk
for i, x in enumerate(info):
if x.linked_data.pk == last_link_pk:
temp_data.extend(create_temp_array(x, x.normalized.additional_normal))
last_link_pk = x.linked_data.pk
else:
final_data.append(temp_data)
temp_data = []
temp_data.extend(create_temp_array(x))
last_link_pk = x.linked_data.pk
if info.count() - 1 == i:
final_data.append(temp_data)
return Response(final_data)
Создание иерархии объектов по значению поля main
в модели LinkedInfo
:
def create_temp_array(data, additional_result=None):
additional = data.normalized.additional_normal.filter(normal=data.normalized.pk).values()
result = [{
'linked_data_id': data.linked_data.pk,
'is_main': data.main,
'normalized_object_id': data.normalized.pk,
'name_data': data.normalized.name_data,
'year_data': data.normalized.year_data.year,
'build_code': data.normalized.build_code,
'ministry_code': data.normalized.ministry_code,
'territory_code': data.normalized.territory_code,
'fcp': data.normalized.program_code,
'max_percentage_technical_readiness': data.max_percentage,
'additional': additional
}]
return result
data.normalized.additional_normal.filter(normal=data.normalized.pk).values()
выполняет каждый вызов метода create_temp_array()
(как и должно быть), но я просто не могу найти другой способ поместить данные из Additional_object в созданный массив.
Каждыйобъект ObjectDataNormalized
может иметь несколько объектов ObjectDataAdditional
их соединение установлено в модели ObjectDataAdditional
в поле normal
.
Я попытался создать промежуточную таблицу с двумя ForeignKey
и добавить поле ManyToMany
введите ObjectDataNormalized
модель, на которую ссылается ObjectDataAdditional
. Но всегда есть некоторые проблемы. Сейчас, насколько я вижу, я могу создать JSON
, в котором я нуждаюсь, но этот способ чрезвычайно плох, потому что он не совсем оптимален, каждый раз, когда создается новый объект, также появляется новый запрос к БД.
Когда я повторяю (для цикла) x.normalized.additional_normal
Я получаю
Объект «RelatedManager» не повторяется
, если я делаю это x.normalized.additional_normal
:
build_analyzer.ObjectDataAdditional.None
Я пробовал много разных способов получить данные из ObjectDataAdditional
, но он всегда отвечает мне ошибками.