Я нашел решение для того, что хотел ... Структура ответа JSON отличается от того, что я определил в моем вопросе выше, но я думаю, что он намного лучше.
Тем не менее, я публикую здесь код, потому что у меня возникают другие мысли о моем подходе, то есть я начинаю думать, что запрос очень дорогой ... и, возможно, кто-то может помочь проверить, хорошо ли он в целом или действительно плохая практика.
Код:
roles = RoleAssignment.objects.none()
modules = RoleModule.objects.none()
module_objects = ModuleObject.objects.none()
objects = Object.objects.none()
permissions = PermissionAssignment.objects.none()
roles = RoleAssignment.objects.filter(user=user).values('role__id', 'role__name')
for role in roles:
modules |= RoleModule.objects.filter(role=role['role__id']).values(
'role__id',
'module__id',
'module__name',
'module__slug',
'module__fontawesome_icon'
)
permissions |= PermissionAssignment.objects.filter(role=role['role__id']).values(
'permission__object__id',
'permission__object__name',
'permission__operation__id',
'permission__operation__name'
)
for module in modules:
module_objects |= ModuleObject.objects.filter(module=module['module__id']).values(
'module__id',
'module__name',
'object__id',
'object__name',
'object__slug'
)
# format modules to include respective objects and permissions
# this logic is primarily designed so that sidebar links can be...
# ...generated seamlessly thru frontend
formatted_modules = [
{
"name": x['module__name'],
"slug": x['module__slug'],
"icon": x['module__fontawesome_icon'],
"objects": [
{
"name": y['object__name'],
"slug": y['object__slug'],
"operations": [z['permission__operation__name'] for z in permissions if z['permission__object__id']==y['object__id']]
}
for y in module_objects if x['module__id']==y['module__id']
]
}
for x in modules
]
Затем отправьте его как ответ:
return Response({
"modules": formatted_modules
})
Эквивалент JSON:
{
modules: [
{
name: 'Web Content',
slug: 'web-content',
icon: 'fas fa-newspaper',
objects: [
{
name: 'Post',
slug: 'post',
operations: [
'Read',
'Write',
'Modify',
'Delete'
]
}
]
},
{
name: 'Bids and Awards',
slug: 'bids-and-awards',
icon: 'fas fa-project-diagram',
objects: [
{
name: 'SRBP Goods & Services',
slug: 'srbp-goods-services',
operations: [
'Read',
'Write',
'Modify',
'Delete'
]
},
{
name: 'SRBP Infrastructure',
slug: 'srbp-infrastructure',
operations: [
'Read',
'Write',
'Modify',
'Delete'
]
}
]
}
]
}
В моем пользовательском интерфейсе: