Description
Description
Method cms.extensions.toolbar.ExtensionToolbar.get_page_extension_admin()
returns the wrong object and URL, if
djangocms-versioning is configured. The object to be returned is of type MyPageContentExtension
inheriting from cms.extensions.models.PageContentExtension
. The URL to be returned points on the Django admin view to edit this object.
The problem arises because method get_page_extension_admin
determines the PageContentExtension
object through the current page. In a versioned CMS, this however is the wrong approach, because instead it should return the currently edited version of that PageContentExtension
object.
Steps to reproduce
- Install and configure djangocms-versioning.
- Create a proprietary Django model inheriting from
PageContentExtension
. - Register an editor for that proprietary model in the CMS toolbar.
- Edit the page and create multiple versions.
- Access the editor to edit the proprietary object from the CMS toolbar.
Expected behaviour
The proprietary object should be that one associated with the current PageContent
object.
Actual behaviour
The proprietary object instead is associated with the published PageContent
object.
Workaround
I was able to create a workaround for this problem by overriding method get_page_extension_admin
in my own class inheriting from ExtensionToolbar
:
from django.urls import NoReverseMatch, resolve, reverse
@toolbar_pool.register
class MyExtensionToolbar(ExtensionToolbar):
model = MyPageContentExtension
def get_title_extension_admin(self, language=None):
urls = []
resolver_match = resolve(self.request.path)
if resolver_match.view_name != 'admin:cms_placeholder_render_object_edit':
return super().get_title_extension_admin(language)
page_content = PageContent.admin_manager.get(id=resolver_match.args[1])
try:
page_extension = self.model.objects.get(extended_object_id=page_content.pk)
except self.model.DoesNotExist:
page_extension = None
model_name = self.model.__name__.lower()
kwargs = {'app_label': self.model._meta.app_label, 'model_name': model_name}
try:
if page_extension:
urls.append((page_content, admin_reverse(
'{app_label}_{model_name}_change'.format(**kwargs),
args=(page_extension.pk,)
)))
else:
urls.append((page_content, '{0}?extended_object={1}'.format(
admin_reverse('{app_label}_{model_name}_add'.format(**kwargs)),
page_content.pk,
)))
except NoReverseMatch:
pass
return urls
def populate(self):
# ... as documented
This however would only work if django-CMS is configured to be used in combination with djangocms-versioning.
- Yes, I want to help fix this issue and I will join #workgroup-pr-review on Slack to confirm with the community that a PR is welcome.
- No, I only want to report the issue.