diff --git a/river/apps.py b/river/apps.py index 1d3b07e..a6e1062 100644 --- a/river/apps.py +++ b/river/apps.py @@ -53,7 +53,7 @@ def _register_hook_inlines(self, model): # pylint: disable=no-self-use registered_admin = admin.site._registry.get(model, None) if registered_admin: if OnApprovedHookInline not in registered_admin.inlines: - registered_admin.inlines = list(set(registered_admin.inlines + [OnApprovedHookInline, OnTransitHookInline, OnCompleteHookInline])) + registered_admin.inlines = list(set(registered_admin.inlines).union([OnApprovedHookInline, OnTransitHookInline, OnCompleteHookInline])) registered_admin.readonly_fields = list(set(list(registered_admin.readonly_fields) + list(workflow_registry.get_class_fields(model)))) admin.site._registry[model] = registered_admin else: diff --git a/river/driver/orm_driver.py b/river/driver/orm_driver.py index 163df96..039833f 100644 --- a/river/driver/orm_driver.py +++ b/river/driver/orm_driver.py @@ -23,23 +23,27 @@ def get_available_approvals(self, as_user): name="workflow_object" ) + approvals_with_max_priority = those_with_max_priority.join( self._authorized_approvals(as_user), - workflow_id=those_with_max_priority.col.workflow_id, + workflow_id=those_with_max_priority.col.workflow, object_id=those_with_max_priority.col.object_id, - transition_id=those_with_max_priority.col.transition_id, + transition_id=those_with_max_priority.col.transition, ).with_cte( those_with_max_priority ).annotate( object_id_as_str=Cast('object_id', CharField(max_length=200)), min_priority=those_with_max_priority.col.min_priority ).filter(min_priority=F("priority")) - return workflow_objects.join( - approvals_with_max_priority, object_id_as_str=Cast(workflow_objects.col.pk, CharField(max_length=200)) + approvals_with_max_priority, + object_id_as_str=Cast(workflow_objects.col.pk, CharField(max_length=200)) ).with_cte( workflow_objects - ).filter(transition__source_state=getattr(workflow_objects.col, self.field_name + "_id")) + ).filter( + transition__source_state=getattr(workflow_objects.col, self.field_name + "_id") + ) + def _authorized_approvals(self, as_user): group_q = Q() diff --git a/river/migrations/0002_alter_function_id_and_more.py b/river/migrations/0002_alter_function_id_and_more.py new file mode 100644 index 0000000..fd8e2bb --- /dev/null +++ b/river/migrations/0002_alter_function_id_and_more.py @@ -0,0 +1,119 @@ +# Generated by Django 5.2.7 on 2025-11-04 07:03 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('river', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='function', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='onapprovedhook', + name='callback_function', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.function', verbose_name='Function'), + ), + migrations.AlterField( + model_name='onapprovedhook', + name='hook_type', + field=models.CharField(choices=[('BEFORE', 'Before'), ('AFTER', 'After')], max_length=50, verbose_name='When?'), + ), + migrations.AlterField( + model_name='onapprovedhook', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='onapprovedhook', + name='workflow', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.workflow', verbose_name='Workflow'), + ), + migrations.AlterField( + model_name='oncompletehook', + name='callback_function', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.function', verbose_name='Function'), + ), + migrations.AlterField( + model_name='oncompletehook', + name='hook_type', + field=models.CharField(choices=[('BEFORE', 'Before'), ('AFTER', 'After')], max_length=50, verbose_name='When?'), + ), + migrations.AlterField( + model_name='oncompletehook', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='oncompletehook', + name='workflow', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.workflow', verbose_name='Workflow'), + ), + migrations.AlterField( + model_name='ontransithook', + name='callback_function', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.function', verbose_name='Function'), + ), + migrations.AlterField( + model_name='ontransithook', + name='hook_type', + field=models.CharField(choices=[('BEFORE', 'Before'), ('AFTER', 'After')], max_length=50, verbose_name='When?'), + ), + migrations.AlterField( + model_name='ontransithook', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='ontransithook', + name='workflow', + field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(app_label)s_%(class)s_hooks', to='river.workflow', verbose_name='Workflow'), + ), + migrations.AlterField( + model_name='state', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='transition', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='transition', + name='status', + field=models.CharField(choices=[('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done'), ('jumped', 'Jumped')], default='pending', max_length=100, verbose_name='Status'), + ), + migrations.AlterField( + model_name='transitionapproval', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='transitionapproval', + name='status', + field=models.CharField(choices=[('pending', 'Pending'), ('approved', 'Approved'), ('cancelled', 'Cancelled'), ('jumped', 'Jumped')], default='pending', max_length=100, verbose_name='Status'), + ), + migrations.AlterField( + model_name='transitionapprovalmeta', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='transitionmeta', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + migrations.AlterField( + model_name='workflow', + name='id', + field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + ] diff --git a/river/models/base_model.py b/river/models/base_model.py index c34f46b..fdd6631 100644 --- a/river/models/base_model.py +++ b/river/models/base_model.py @@ -1,7 +1,7 @@ from django.conf import settings from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models.managers.rivermanager import RiverManager diff --git a/river/models/function.py b/river/models/function.py index 490e84e..36d1e07 100644 --- a/river/models/function.py +++ b/river/models/function.py @@ -3,7 +3,7 @@ from django.db import models from django.db.models.signals import pre_save -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models import BaseModel diff --git a/river/models/hook.py b/river/models/hook.py index e4d3984..3edca33 100644 --- a/river/models/hook.py +++ b/river/models/hook.py @@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models import PROTECT -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models import Workflow, GenericForeignKey, BaseModel from river.models.function import Function diff --git a/river/models/on_approved_hook.py b/river/models/on_approved_hook.py index cf15d68..4b78b74 100644 --- a/river/models/on_approved_hook.py +++ b/river/models/on_approved_hook.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models import CASCADE -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models import TransitionApprovalMeta, TransitionApproval from river.models.hook import Hook diff --git a/river/models/on_transit_hook.py b/river/models/on_transit_hook.py index e6c019e..94c2761 100644 --- a/river/models/on_transit_hook.py +++ b/river/models/on_transit_hook.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models import CASCADE -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models import TransitionMeta, Transition from river.models.hook import Hook diff --git a/river/models/state.py b/river/models/state.py index 12ade30..d4ad67e 100644 --- a/river/models/state.py +++ b/river/models/state.py @@ -9,7 +9,7 @@ except ImportError: from six import python_2_unicode_compatible -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models.base_model import BaseModel from river.models.managers.state import StateManager diff --git a/river/models/transition.py b/river/models/transition.py index b295273..7481e38 100644 --- a/river/models/transition.py +++ b/river/models/transition.py @@ -4,13 +4,10 @@ from river.models import State, Workflow, TransitionMeta -try: - from django.contrib.contenttypes.fields import GenericForeignKey -except ImportError: - from django.contrib.contenttypes.generic import GenericForeignKey +from django.contrib.contenttypes.fields import GenericForeignKey from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models.base_model import BaseModel from river.models.managers.transitionapproval import TransitionApprovalManager diff --git a/river/models/transitionapproval.py b/river/models/transitionapproval.py index 92964d3..97b845d 100644 --- a/river/models/transitionapproval.py +++ b/river/models/transitionapproval.py @@ -6,13 +6,10 @@ from river.models import TransitionApprovalMeta, Workflow from river.models.transition import Transition -try: - from django.contrib.contenttypes.fields import GenericForeignKey -except ImportError: - from django.contrib.contenttypes.generic import GenericForeignKey +from django.contrib.contenttypes.fields import GenericForeignKey from django.db import models -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models.base_model import BaseModel from river.models.managers.transitionapproval import TransitionApprovalManager diff --git a/river/models/transitionapprovalmeta.py b/river/models/transitionapprovalmeta.py index b1c2f74..003929f 100644 --- a/river/models/transitionapprovalmeta.py +++ b/river/models/transitionapprovalmeta.py @@ -3,7 +3,7 @@ from django.db import models, transaction from django.db.models import PROTECT from django.db.models.signals import post_save, pre_delete -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.config import app_config from river.models import Workflow diff --git a/river/models/transitionmeta.py b/river/models/transitionmeta.py index 224bdf9..b4f7c62 100644 --- a/river/models/transitionmeta.py +++ b/river/models/transitionmeta.py @@ -2,7 +2,7 @@ from django.db import models from django.db.models import PROTECT -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.models import State, Workflow from river.models.base_model import BaseModel diff --git a/river/models/workflow.py b/river/models/workflow.py index aee0901..38d494e 100644 --- a/river/models/workflow.py +++ b/river/models/workflow.py @@ -1,6 +1,6 @@ from django.db import models from django.db.models import PROTECT -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from river.config import app_config from river.models import BaseModel, State diff --git a/river/signals.py b/river/signals.py index bc1ff44..9dbcf30 100644 --- a/river/signals.py +++ b/river/signals.py @@ -10,14 +10,14 @@ from river.models.on_complete_hook import OnCompleteHook from river.models.on_transit_hook import OnTransitHook -pre_on_complete = Signal(providing_args=["workflow_object", "field_name", ]) -post_on_complete = Signal(providing_args=["workflow_object", "field_name", ]) +pre_on_complete = Signal() +post_on_complete = Signal() -pre_transition = Signal(providing_args=["workflow_object", "field_name", "source_state", "destination_state"]) -post_transition = Signal(providing_args=["workflow_object", "field_name", "source_state", "destination_state"]) +pre_transition = Signal() +post_transition = Signal() -pre_approve = Signal(providing_args=["workflow_object", "field_name", "transition_approval"]) -post_approve = Signal(providing_args=["workflow_object", "field_name", "transition_approval", "transition_approval_meta"]) +pre_approve = Signal() +post_approve = Signal() LOGGER = logging.getLogger(__name__)