GithubHelp home page GithubHelp logo

Comments (19)

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya do you think the line i mentioned might just be in the wrong place??

from django-river.

javrasya avatar javrasya commented on June 30, 2024

@psychok7 I couldn't check that yet. Will look at it soon.

from django-river.

javrasya avatar javrasya commented on June 30, 2024

It might somehow contribute your model more than once if you are sure there is only one state field in your model.

Instead of commenting it out, we should check that, is that class is registered before WITH MULTIPLE DIFFERENT FIELDS. It should raise an exception if there are more than one state field with the different name.

Could you debug it, does it hit that line for same fields? I suspect that django sometimes does that which is triggering contribute_to_class method of model fields twice.

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya i don't think i understood what line you want me to debug, but i added :

        if id(cls) in classes:
            # import ipdb;ipdb.set_trace()
            raise RiverException(ErrorCode.MULTIPLE_STATE_FIELDS, "There can be only one state field in a model class.")

        print("(cls): ", cls)
        classes.append(id(cls))

I got <class '__fake__.QRequest'> multiple times in the print with different ids(cls) right up until where it raised the error (the id must have been equal at that point).

If you want me to debug something else let me know the exact line.
thanks

from django-river.

javrasya avatar javrasya commented on June 30, 2024

@psychok7 it probably hits that line more than once;

if id(cls) in classes:

Can you just look at self.name variable which is actual field name at that line. I wonder that, does it hit that line for the same field more than once.

This line of code tries to guarantee not having multiple state fields in a model. We shouldn't remove it. We should fix it somehow.

If it hit that line for the same field(which you can detect by looking at the field name variable) for more than once, I think I can fix it.

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya yes it hits the line multiple times but with None:

        if id(cls) in classes:
            print("self.name: ", self.name)
            print("There can be only one state field in a model class.")
            # raise RiverException(ErrorCode.MULTIPLE_STATE_FIELDS, "There can be only one state field in a model class.")

i get :

Destroying old test database for alias 'default'...
self.name:  None
There can be only one state field in a model class.
self.name:  None
There can be only one state field in a model class.
self.name:  None
There can be only one state field in a model class.
self.name:  None
There can be only one state field in a model class.

from django-river.

javrasya avatar javrasya commented on June 30, 2024

Can you try with name instead of self.name, sorry to bother you.

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya no problem, with name i get:

Destroying old test database for alias 'default'...
name:  status
There can be only one state field in a model class.
name:  status
There can be only one state field in a model class.
name:  status
There can be only one state field in a model class.

from django-river.

javrasya avatar javrasya commented on June 30, 2024

@psychok7 OK, this is exactly, what I thought. Django triggers that whole function for more than one for the same field. I will try to fix this.

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya ok, let me know when you finish and i will test it again ;)

from django-river.

javrasya avatar javrasya commented on June 30, 2024

@psychok7 can you test it with master branch once again.

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya i tested it but i now get another error:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/django/db/models/options.py", line 617, in get_field
    return self.fields_map[field_name]
KeyError: 'status'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/test.py", line 29, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 549, in run_tests
    old_config = self.setup_databases()
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 499, in setup_databases
    self.parallel, **kwargs
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 743, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/creation.py", line 70, in create_test_db
    run_syncdb=True,
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 130, in call_command
    return command.execute(*args, **defaults)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/usr/local/lib/python3.5/dist-packages/django/db/migrations/operations/fields.py", line 147, in database_forwards
    schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
  File "/usr/local/lib/python3.5/dist-packages/django/db/models/options.py", line 619, in get_field
    raise FieldDoesNotExist('%s has no field named %r' % (self.object_name, field_name))
django.core.exceptions.FieldDoesNotExist: Qualif has no field named 'status'

My model does have the status field.

from django-river.

javrasya avatar javrasya commented on June 30, 2024

When you are getting this error, can you share your test case?

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya am not sure. i ran only one test with python3 manage.py test entities.test_api --noinput. The thing is this model doesn't even have django-river in it. It look like something happens at the migration stage idk. Anways here is my testcase with a model without river:

class EntityAPITests(TestCase):
    def setUp(self):
        self.client = APIClient(enforce_csrf_checks=True)
        self.user = UserFactory()
        self.token = Token.objects.get(user=self.user)

    def test_200_separator(self):
        self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
        response = self.client.get(reverse('entitystaff-list'))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertTrue(response.data)

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya if i revert to the previous commit i get the other error msg so it must be something with the change you made in MASTER i think. if i remove the RAISE with the old code, then my tests run just fine.

from django-river.

javrasya avatar javrasya commented on June 30, 2024

@psychok7 I don't face that issue. Can you replace contribute_to_class method with this and let me know does that work;

    def contribute_to_class(self, cls, name, virtual_only=False):
        def is_workflow_completed(workflow_object):
            return ObjectService.is_workflow_completed(workflow_object)

        def proceed(self, user, *args, **kwargs):
            TransitionService.proceed(self, user, *args, **kwargs)

        @property
        def on_initial_state(self):
            from river.services.state import StateService

            return StateService.get_initial_state(ContentType.objects.get_for_model(self)) == self.get_state()

        @property
        def on_final_state(self):
            from river.services.state import StateService

            return self.get_state() in StateService.get_final_states(ContentType.objects.get_for_model(self))

        def get_initial_state(self):
            from river.services.state import StateService

            return StateService.get_initial_state(ContentType.objects.get_for_model(self))

        def get_available_proceedings(self, *args, **kwargs):
            from river.services.proceeding import ProceedingService

            return ProceedingService.get_available_proceedings(self, [self.get_state()], *args, **kwargs)

        @property
        def initial_proceedings(self):
            from river.services.proceeding import ProceedingService

            return self.get_state() in ProceedingService.get_initial_proceedings(ContentType.objects.get_for_model(self))

        @property
        def final_proceedings(self):
            from river.services.proceeding import ProceedingService

            return self.get_state() in ProceedingService.get_final_proceedings(ContentType.objects.get_for_model(self))

        @property
        def next_proceedings(self):
            from river.services.proceeding import ProceedingService

            return self.get_state() in ProceedingService.get_next_proceedings(ContentType.objects.get_for_model(self))

        @property
        def proceeding(self):
            try:
                return self.proceedings.filter(transaction_date__isnull=False).latest('transaction_date')
            except Proceeding.DoesNotExist:
                return None

        def _get_state(self):
            return getattr(self, name)

        def _set_state(self, state):
            setattr(self, name, state)

        field_identifiers = [_get_identifier(c, f) for c, f in class_field_rl.items()]
        cls_identifier = _get_cls_identifier(cls)
        field_identifier = _get_identifier(cls_identifier, name)
        if field_identifier not in field_identifiers:

            if cls_identifier in class_field_rl.keys():
                raise RiverException(ErrorCode.MULTIPLE_STATE_FIELDS,
                                     "There can be only one state field in a model class. Class:%s - Field:%s." % (cls.__name__, name))

            class_field_rl[cls_identifier] = name

        self.model = cls
        self.__add_to_class(cls, "proceedings", GenericRelation('%s.%s' % (Proceeding._meta.app_label, Proceeding._meta.object_name)))
        self.__add_to_class(cls, "proceeding", proceeding)

        self.__add_to_class(cls, "is_workflow_completed", is_workflow_completed)
        self.__add_to_class(cls, "proceed", proceed)

        self.__add_to_class(cls, "on_initial_state", on_initial_state)
        self.__add_to_class(cls, "on_final_state", on_final_state)

        self.__add_to_class(cls, "get_initial_state", get_initial_state)
        self.__add_to_class(cls, "get_available_proceedings", get_available_proceedings)

        self.__add_to_class(cls, "initial_proceedings", initial_proceedings)
        self.__add_to_class(cls, "final_proceedings", final_proceedings)
        self.__add_to_class(cls, "next_proceedings", next_proceedings)

        self.__add_to_class(cls, "get_state", _get_state)
        self.__add_to_class(cls, "set_state", _set_state)

        super(StateField, self).contribute_to_class(cls, name, virtual_only=virtual_only)

        post_save.connect(_post_save, self.model, False, dispatch_uid='%s_%s_riverstatefield_post' % (self.model, name))

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya there is now a different error lol:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "river_testmodel" does not exist
LINE 1: ...test_field", "river_testmodel"."my_field_id" FROM "river_tes...
                                                             ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/test.py", line 29, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/base.py", line 345, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/management/commands/test.py", line 72, in handle
    failures = test_runner.run_tests(test_labels)
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 549, in run_tests
    old_config = self.setup_databases()
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 499, in setup_databases
    self.parallel, **kwargs
  File "/usr/local/lib/python3.5/dist-packages/django/test/runner.py", line 743, in setup_databases
    serialize=connection.settings_dict.get("TEST", {}).get("SERIALIZE", True),
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/creation.py", line 78, in create_test_db
    self.connection._test_serialized_contents = self.serialize_db_to_string()
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/creation.py", line 122, in serialize_db_to_string
    serializers.serialize("json", get_objects(), indent=None, stream=out)
  File "/usr/local/lib/python3.5/dist-packages/django/core/serializers/__init__.py", line 129, in serialize
    s.serialize(queryset, **options)
  File "/usr/local/lib/python3.5/dist-packages/django/core/serializers/base.py", line 79, in serialize
    for count, obj in enumerate(queryset, start=1):
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/base/creation.py", line 118, in get_objects
    for obj in queryset.iterator():
  File "/usr/local/lib/python3.5/dist-packages/django/db/models/query.py", line 54, in __iter__
    results = compiler.execute_sql()
  File "/usr/local/lib/python3.5/dist-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python3.5/dist-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python3.5/dist-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.5/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "river_testmodel" does not exist
LINE 1: ...test_field", "river_testmodel"."my_field_id" FROM "river_tes...

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya any ideas on this "new" error?

from django-river.

psychok7 avatar psychok7 commented on June 30, 2024

@javrasya i figured it out. the issue was now on my end because i had the river tests folder inside my project. i removed it and everything now works with the new piece of code you added here. I will create a PR with that code so that you don't have to

from django-river.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.