From 4fc17bbb2b29f8e482b1919228fa8b36b1b2c2d1 Mon Sep 17 00:00:00 2001 From: ShyamSundhar1411 Date: Wed, 19 Nov 2025 15:25:18 +0530 Subject: [PATCH 1/4] feat: migrating to django 5 --- river/apps.py | 2 +- river/core/instanceworkflowobject.py | 1 + river/driver/orm_driver.py | 14 ++- .../0002_alter_function_id_and_more.py | 119 ++++++++++++++++++ river/models/base_model.py | 2 +- river/models/function.py | 2 +- river/models/hook.py | 2 +- river/models/on_approved_hook.py | 2 +- river/models/on_transit_hook.py | 2 +- river/models/state.py | 2 +- river/models/transition.py | 4 +- river/models/transitionapproval.py | 4 +- river/models/transitionapprovalmeta.py | 2 +- river/models/transitionmeta.py | 2 +- river/models/workflow.py | 2 +- river/signals.py | 12 +- 16 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 river/migrations/0002_alter_function_id_and_more.py diff --git a/river/apps.py b/river/apps.py index 1d3b07e..da80c85 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(list(registered_admin.inlines) + [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/core/instanceworkflowobject.py b/river/core/instanceworkflowobject.py index ceccb1b..4b0b5e8 100644 --- a/river/core/instanceworkflowobject.py +++ b/river/core/instanceworkflowobject.py @@ -109,6 +109,7 @@ def get_available_states(self, as_user=None): return State.objects.filter(pk__in=all_destination_state_ids) def get_available_approvals(self, as_user=None, destination_state=None): + print("Workflow object",self.workflow_object.pk) qs = self.class_workflow.get_available_approvals(as_user, ).filter(object_id=self.workflow_object.pk) if destination_state: qs = qs.filter(transition__destination_state=destination_state) 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..d4b1c87 100644 --- a/river/models/transition.py +++ b/river/models/transition.py @@ -7,10 +7,10 @@ try: from django.contrib.contenttypes.fields import GenericForeignKey except ImportError: - from django.contrib.contenttypes.generic import GenericForeignKey + from django.contrib.contenttypes 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..91c3125 100644 --- a/river/models/transitionapproval.py +++ b/river/models/transitionapproval.py @@ -9,10 +9,10 @@ try: from django.contrib.contenttypes.fields import GenericForeignKey except ImportError: - from django.contrib.contenttypes.generic import GenericForeignKey + from django.contrib.contenttypes 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__) From ca1fa063faf3f767cd7f5c9651edb55977c45fb9 Mon Sep 17 00:00:00 2001 From: asu-dev-1 Date: Wed, 26 Nov 2025 12:05:18 +0530 Subject: [PATCH 2/4] fix: gemini issues --- river/apps.py | 2 +- river/core/instanceworkflowobject.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/river/apps.py b/river/apps.py index da80c85..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(list(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/core/instanceworkflowobject.py b/river/core/instanceworkflowobject.py index 4b0b5e8..ceccb1b 100644 --- a/river/core/instanceworkflowobject.py +++ b/river/core/instanceworkflowobject.py @@ -109,7 +109,6 @@ def get_available_states(self, as_user=None): return State.objects.filter(pk__in=all_destination_state_ids) def get_available_approvals(self, as_user=None, destination_state=None): - print("Workflow object",self.workflow_object.pk) qs = self.class_workflow.get_available_approvals(as_user, ).filter(object_id=self.workflow_object.pk) if destination_state: qs = qs.filter(transition__destination_state=destination_state) From 0b2b5abd0787981a4867f2faf70b7a89ae4a374d Mon Sep 17 00:00:00 2001 From: asu-dev-1 Date: Wed, 26 Nov 2025 12:07:30 +0530 Subject: [PATCH 3/4] fix: gemini high priorities --- river/models/transition.py | 5 +---- river/models/transitionapproval.py | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/river/models/transition.py b/river/models/transition.py index d4b1c87..0698dcd 100644 --- a/river/models/transition.py +++ b/river/models/transition.py @@ -4,10 +4,7 @@ from river.models import State, Workflow, TransitionMeta -try: - from django.contrib.contenttypes.fields import GenericForeignKey -except ImportError: - from django.contrib.contenttypes import GenericForeignKey +from django.contrib.contenttypes import GenericForeignKey from django.db import models from django.utils.translation import gettext_lazy as _ diff --git a/river/models/transitionapproval.py b/river/models/transitionapproval.py index 91c3125..371e9ab 100644 --- a/river/models/transitionapproval.py +++ b/river/models/transitionapproval.py @@ -6,10 +6,7 @@ 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 import GenericForeignKey +from django.contrib.contenttypes import GenericForeignKey from django.db import models from django.utils.translation import gettext_lazy as _ From 2b16d5a36fe1e1c38b2546cc1659d16e6a5a5e47 Mon Sep 17 00:00:00 2001 From: asu-dev-1 Date: Wed, 26 Nov 2025 12:14:50 +0530 Subject: [PATCH 4/4] fix: gemini high priorities --- river/models/transition.py | 2 +- river/models/transitionapproval.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/river/models/transition.py b/river/models/transition.py index 0698dcd..7481e38 100644 --- a/river/models/transition.py +++ b/river/models/transition.py @@ -4,7 +4,7 @@ from river.models import State, Workflow, TransitionMeta -from django.contrib.contenttypes import GenericForeignKey +from django.contrib.contenttypes.fields import GenericForeignKey from django.db import models from django.utils.translation import gettext_lazy as _ diff --git a/river/models/transitionapproval.py b/river/models/transitionapproval.py index 371e9ab..97b845d 100644 --- a/river/models/transitionapproval.py +++ b/river/models/transitionapproval.py @@ -6,7 +6,7 @@ from river.models import TransitionApprovalMeta, Workflow from river.models.transition import Transition -from django.contrib.contenttypes import GenericForeignKey +from django.contrib.contenttypes.fields import GenericForeignKey from django.db import models from django.utils.translation import gettext_lazy as _