Skip to content

Merge first and second level menu items#550

Open
frcroth wants to merge 75 commits intofsr-de:mainfrom
frcroth:merge-menu-items
Open

Merge first and second level menu items#550
frcroth wants to merge 75 commits intofsr-de:mainfrom
frcroth:merge-menu-items

Conversation

@frcroth
Copy link
Copy Markdown
Contributor

@frcroth frcroth commented Apr 7, 2024

Backup before applying these migrations would be wise.

@frcroth frcroth requested a review from jeriox April 7, 2024 12:51
lukasrad02
lukasrad02 previously approved these changes Apr 8, 2024
@lukasrad02 lukasrad02 dismissed their stale review April 9, 2024 10:15

Noticed an error during the migration on production data

@lukasrad02
Copy link
Copy Markdown
Contributor

When testing your migration on a database with production data, the following error is thrown:

Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.ObjectInUse: cannot DROP TABLE "core_firstlevelmenuitem" because it has pending trigger events


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

Traceback (most recent call last):
  File "/app/manage.py", line 13, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 356, in handle
    post_migrate_state = executor.migrate(
                         ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
            ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 252, in apply_migration
    state = migration.apply(state, schema_editor)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/migrations/migration.py", line 132, in apply
    operation.database_forwards(
  File "/usr/local/lib/python3.11/site-packages/django/db/migrations/operations/models.py", line 389, in database_forwards
    schema_editor.delete_model(model)
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 487, in delete_model
    self.execute(
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/postgresql/schema.py", line 48, in execute
    return super().execute(sql, None)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/schema.py", line 201, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 87, in _execute
    return self.cursor.execute(sql)
           ^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.OperationalError: cannot DROP TABLE "core_firstlevelmenuitem" because it has pending trigger events

Could be related to https://stackoverflow.com/a/12838113, as this error does not occur when splitting the RunPython and DeleteModel calls from migration 0013 into two separate migrations.

@frcroth frcroth force-pushed the merge-menu-items branch from e84b301 to 6e7e985 Compare April 9, 2024 19:07
@frcroth frcroth requested a review from lukasrad02 April 9, 2024 19:07
Comment thread myhpi/core/models.py Outdated

class FirstLevelMenuItem(BasePage):
class MenuItem(BasePage):
parent_page_types = ["RootPage"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MenuItem is missing here

@frcroth frcroth requested a review from lukasrad02 April 10, 2024 17:26
@lukasrad02
Copy link
Copy Markdown
Contributor

I've just noticed that the visible_for permissions are lost on all menu items after applying the migration.

@frcroth
Copy link
Copy Markdown
Contributor Author

frcroth commented Apr 11, 2024

I've just noticed that the visible_for permissions are lost on all menu items after applying the migration.

Hmm, for me with sqlite this is not the case. Need to investigate

@lukasrad02
Copy link
Copy Markdown
Contributor

I was able to reproduce it in the local setup with SQLite using the following steps:

  1. Check out the latest commit on the main branch
  2. Ensure all packages are up-to-date
  3. Re-create the database (rm db.sqlite3; python manage.py migrate)
  4. Populate the database with test data and create a superuser
  5. Run the server.
  6. Check that the "Study Council" menu item from the test data is indeed visible for "Student"
  7. Stop the server
  8. Check out the latest commit of this PR
  9. Migrate the database
  10. Run the server
  11. The "Study Council" menu item has now lost its visible for permissions

@frcroth
Copy link
Copy Markdown
Contributor Author

frcroth commented Apr 12, 2024

I'm stumped on how to fix this. Setting the visible_for value in the shell later works in the way it is done in the migration (I also tried using set() suggested by ChatGPT), also stepping through it seems visible_for is set for the new item. Maybe the delete of the old menuitem triggers the removal of the relationship at a later point and thus the newly set relationship is then deleted again?
Any ideas @jeriox ?

@lukasrad02
Copy link
Copy Markdown
Contributor

Maybe the delete of the old menuitem triggers the removal of the relationship at a later point and thus the newly set relationship is then deleted again?

Even without migration 0014 (deletion of old menu item models), the permissions are still lost for me.

@frcroth
Copy link
Copy Markdown
Contributor Author

frcroth commented Apr 13, 2024

Maybe the delete of the old menuitem triggers the removal of the relationship at a later point and thus the newly set relationship is then deleted again?

Even without migration 0014 (deletion of old menu item models), the permissions are still lost for me.

Yes I mean the individual object delete() calls

Comment thread myhpi/core/migrations/0013_merge_first_and_second_level_menu_items.py Outdated
@lukasrad02
Copy link
Copy Markdown
Contributor

The migration now preserves permission. However, I've received an error when accessing some menu items after the migration. Will investigate…

ERROR 2024-06-11 11:24:48,320 django.request log Internal Server Error: /admin/pages/66/
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/views/decorators/cache.py", line 62, in _wrapper_view_func
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/urls/__init__.py", line 173, in wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/auth.py", line 151, in decorated_view
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/generic/permissions.py", line 31, in dispatch
    return super().dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/pages/listing.py", line 221, in get
    return super().get(request)
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/views/generic/list.py", line 174, in get
    context = self.get_context_data()
              ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/pages/listing.py", line 409, in get_context_data
    side_panels = self.get_side_panels()
                  ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/admin/views/pages/listing.py", line 433, in get_side_panels
    self.parent_page.get_latest_revision_as_object(),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/models/__init__.py", line 1759, in get_latest_revision_as_object
    return latest_revision.as_object()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/wagtail/models/__init__.py", line 2820, in as_object
    return self.content_object.with_content_json(self.content)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/contrib/contenttypes/fields.py", line 253, in __get__
    rel_obj = ct.get_object_for_this_type(pk=pk_val)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/django/contrib/contenttypes/models.py", line 181, in get_object_for_this_type
    return self.model_class()._base_manager.using(self._state.db).get(**kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '_base_manager'

@frcroth
Copy link
Copy Markdown
Contributor Author

frcroth commented Aug 2, 2024

@lukasrad02 Did you have any further insights on this?

@lukasrad02
Copy link
Copy Markdown
Contributor

Sorry, I've been tracing down the wrong path for quite a while, but I think I have identified the underlying issue now.

The revision model from wagatil references the object it is a revision of. This includes the type of model: https://github.com/wagtail/wagtail/blob/72b965cd94726e9fa0ceb64f10ef7ef88476fb2c/wagtail/models/__init__.py#L2866C5-L2868C6. After our migration, the revisions of the menu items are still pointing to content types firstlevelmenuitem or secondlevelmenuitem, which causes errors when interacting with the revision.

I have set the correct page.latest.revision.content_type on the page causing the error manually in the python shell and was able to visit /admin/pages/66/ afterwards. For some reason, there are also pages with an incorrect content_type on their latest revision that do not cause an error when viewing them in the admin interface, but calling revision.as_object() on them in the python shell still fails.

I would propose to update the content_type of all revisions of all menu items in the migration.

lukasrad02 and others added 5 commits October 22, 2024 17:42
Bumps [django-debug-toolbar](https://github.com/jazzband/django-debug-toolbar) from 4.3.0 to 4.4.2.
- [Release notes](https://github.com/jazzband/django-debug-toolbar/releases)
- [Changelog](https://github.com/jazzband/django-debug-toolbar/blob/main/docs/changes.rst)
- [Commits](django-commons/django-debug-toolbar@4.3...4.4.2)

---
updated-dependencies:
- dependency-name: django-debug-toolbar
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [wagtail-markdown](https://github.com/torchbox/wagtail-markdown) from 0.11.1 to 0.12.1.
- [Release notes](https://github.com/torchbox/wagtail-markdown/releases)
- [Changelog](https://github.com/torchbox/wagtail-markdown/blob/main/CHANGELOG.md)
- [Commits](torchbox/wagtail-markdown@v0.11.1...v0.12.1)

---
updated-dependencies:
- dependency-name: wagtail-markdown
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.5.1 to 7.5.3.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](coveragepy/coveragepy@7.5.1...7.5.3)

---
updated-dependencies:
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.1.0 to 3.2.3.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](pylint-dev/pylint@v3.1.0...v3.2.3)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
dependabot bot and others added 25 commits October 22, 2024 17:42
Bumps [django-bootstrap-icons](https://github.com/christianwgd/django-bootstrap-icons) from 0.8.7 to 0.9.0.
- [Release notes](https://github.com/christianwgd/django-bootstrap-icons/releases)
- [Changelog](https://github.com/christianwgd/django-bootstrap-icons/blob/master/CHANGELOG.md)
- [Commits](christianwgd/django-bootstrap-icons@0.8.7...v0.9.0)

---
updated-dependencies:
- dependency-name: django-bootstrap-icons
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.2.5 to 3.2.6.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](pylint-dev/pylint@v3.2.5...v3.2.6)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [django](https://github.com/django/django) from 5.0.6 to 5.0.8.
- [Commits](django/django@5.0.6...5.0.8)

---
updated-dependencies:
- dependency-name: django
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.6.0 to 7.6.1.
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](coveragepy/coveragepy@7.6.0...7.6.1)

---
updated-dependencies:
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [black](https://github.com/psf/black) from 24.4.2 to 24.8.0.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](psf/black@24.4.2...24.8.0)

---
updated-dependencies:
- dependency-name: black
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
* use generated html for TencaListOptionsForm

* Render label as HTML tag connected to the input

* Add field for footer property

Depends on tzwenn/tenca#1

* Use tenca 0.0.3

* Update lockfile

* Run formatter

---------

Co-authored-by: Julian B <jeriox@users.noreply.github.com>
Bumps [djlint](https://github.com/djlint/djLint) from 1.34.1 to 1.35.2.
- [Release notes](https://github.com/djlint/djLint/releases)
- [Changelog](https://github.com/djlint/djLint/blob/master/CHANGELOG.md)
- [Commits](djlint/djLint@v1.34.1...v1.35.2)

---
updated-dependencies:
- dependency-name: djlint
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [wagtail-localize](https://github.com/wagtail/wagtail-localize) from 1.9 to 1.9.1.
- [Release notes](https://github.com/wagtail/wagtail-localize/releases)
- [Changelog](https://github.com/wagtail/wagtail-localize/blob/main/CHANGELOG.md)
- [Commits](wagtail/wagtail-localize@v1.9...v1.9.1)

---
updated-dependencies:
- dependency-name: wagtail-localize
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [wagtail](https://github.com/wagtail/wagtail) from 6.2 to 6.2.1.
- [Release notes](https://github.com/wagtail/wagtail/releases)
- [Changelog](https://github.com/wagtail/wagtail/blob/main/CHANGELOG.txt)
- [Commits](wagtail/wagtail@v6.2...v6.2.1)

---
updated-dependencies:
- dependency-name: wagtail
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pylint](https://github.com/pylint-dev/pylint) from 3.2.6 to 3.3.1.
- [Release notes](https://github.com/pylint-dev/pylint/releases)
- [Commits](pylint-dev/pylint@v3.2.6...v3.3.1)

---
updated-dependencies:
- dependency-name: pylint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.3.2 to 8.3.3.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@8.3.2...8.3.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [django-select2](https://github.com/codingjoe/django-select2) from 8.2.0 to 8.2.1.
- [Release notes](https://github.com/codingjoe/django-select2/releases)
- [Commits](codingjoe/django-select2@8.2.0...8.2.1)

---
updated-dependencies:
- dependency-name: django-select2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@frcroth
Copy link
Copy Markdown
Contributor Author

frcroth commented Oct 24, 2024

@lukasrad02 I updated the content type, you could test it again

Also I guess I messed up the history, but we can squash this

@lukasrad02
Copy link
Copy Markdown
Contributor

Now we're again losing permissions on some menu items. I'll try to investigate further, but on the first glance, I have no idea why only some pages are affected…

@lukasrad02
Copy link
Copy Markdown
Contributor

If I did not miss anything, only second level menu items are affected by the permission loss. Changing the migration 13 so that we first migrate second level menu items fixes the issue and both first- and second-level menu items keep the assigned permissions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

7 participants