mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-04-21 23:39:28 +00:00
Performance: Increases workflow related M2M prefetching (#12618)
This commit is contained in:
@@ -3352,13 +3352,13 @@ class WorkflowSerializer(serializers.ModelSerializer[Workflow]):
|
||||
ManyToMany fields dont support e.g. on_delete so we need to discard unattached
|
||||
triggers and actions manually
|
||||
"""
|
||||
for trigger in WorkflowTrigger.objects.all():
|
||||
if trigger.workflows.all().count() == 0:
|
||||
trigger.delete()
|
||||
WorkflowTrigger.objects.annotate(
|
||||
workflow_count=Count("workflows"),
|
||||
).filter(workflow_count=0).delete()
|
||||
|
||||
for action in WorkflowAction.objects.all():
|
||||
if action.workflows.all().count() == 0:
|
||||
action.delete()
|
||||
WorkflowAction.objects.annotate(
|
||||
workflow_count=Count("workflows"),
|
||||
).filter(workflow_count=0).delete()
|
||||
|
||||
WorkflowActionEmail.objects.filter(action=None).delete()
|
||||
WorkflowActionWebhook.objects.filter(action=None).delete()
|
||||
@@ -3387,16 +3387,6 @@ class WorkflowSerializer(serializers.ModelSerializer[Workflow]):
|
||||
|
||||
return instance
|
||||
|
||||
def to_representation(self, instance: Workflow) -> dict[str, Any]:
|
||||
data = super().to_representation(instance)
|
||||
actions = instance.actions.order_by("order", "pk")
|
||||
data["actions"] = WorkflowActionSerializer(
|
||||
actions,
|
||||
many=True,
|
||||
context=self.context,
|
||||
).data
|
||||
return data
|
||||
|
||||
|
||||
class TrashSerializer(SerializerWithPerms):
|
||||
documents = serializers.ListField(
|
||||
|
||||
@@ -99,6 +99,40 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
||||
self.action.assign_correspondent.pk,
|
||||
)
|
||||
|
||||
def test_api_get_workflow_actions_ordered(self) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
- A workflow with two actions added in reverse order (order=1 before order=0)
|
||||
WHEN:
|
||||
- API is called to get workflows
|
||||
THEN:
|
||||
- Actions are returned sorted by order ascending
|
||||
"""
|
||||
# Created before action_first so its pk is lower — ensures pk order
|
||||
# disagrees with the order field, catching regressions if order_by is removed.
|
||||
action_second = WorkflowAction.objects.create(
|
||||
assign_title="Second action",
|
||||
order=1,
|
||||
)
|
||||
action_first = WorkflowAction.objects.create(
|
||||
assign_title="First action",
|
||||
order=0,
|
||||
)
|
||||
self.workflow.actions.add(action_second)
|
||||
self.workflow.actions.add(action_first)
|
||||
|
||||
response = self.client.get(self.ENDPOINT, format="json")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
resp_actions = response.data["results"][0]["actions"]
|
||||
action_ids = [a["id"] for a in resp_actions]
|
||||
self.assertIn(action_first.id, action_ids)
|
||||
self.assertIn(action_second.id, action_ids)
|
||||
self.assertLess(
|
||||
action_ids.index(action_first.id),
|
||||
action_ids.index(action_second.id),
|
||||
)
|
||||
|
||||
def test_api_create_workflow(self) -> None:
|
||||
"""
|
||||
GIVEN:
|
||||
|
||||
@@ -4485,8 +4485,44 @@ class WorkflowViewSet(ModelViewSet[Workflow]):
|
||||
Workflow.objects.all()
|
||||
.order_by("order")
|
||||
.prefetch_related(
|
||||
"triggers",
|
||||
"actions",
|
||||
Prefetch(
|
||||
"triggers",
|
||||
queryset=WorkflowTrigger.objects.prefetch_related(
|
||||
"filter_has_tags",
|
||||
"filter_has_all_tags",
|
||||
"filter_has_not_tags",
|
||||
"filter_has_any_correspondents",
|
||||
"filter_has_not_correspondents",
|
||||
"filter_has_any_document_types",
|
||||
"filter_has_not_document_types",
|
||||
"filter_has_any_storage_paths",
|
||||
"filter_has_not_storage_paths",
|
||||
),
|
||||
),
|
||||
Prefetch(
|
||||
"actions",
|
||||
queryset=WorkflowAction.objects.order_by(
|
||||
"order",
|
||||
"pk",
|
||||
).prefetch_related(
|
||||
"assign_tags",
|
||||
"assign_view_users",
|
||||
"assign_view_groups",
|
||||
"assign_change_users",
|
||||
"assign_change_groups",
|
||||
"assign_custom_fields",
|
||||
"remove_tags",
|
||||
"remove_correspondents",
|
||||
"remove_document_types",
|
||||
"remove_storage_paths",
|
||||
"remove_custom_fields",
|
||||
"remove_owners",
|
||||
"remove_view_users",
|
||||
"remove_view_groups",
|
||||
"remove_change_users",
|
||||
"remove_change_groups",
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user