Created
October 31, 2018 14:44
-
-
Save benzkji/f9a42667939f74646dbf9d9c996884a8 to your computer and use it in GitHub Desktop.
move first / last cms plugin context menu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# add to your normal cms_plugins.py whateverplugin | |
class DemoPlugin(CMSPluginBase): | |
model = Demo | |
... | |
def get_plugin_urls(self): | |
return [ | |
url(r'^plugin_move_first/$', self.plugin_move_first, name='cmsplugin_move_first'), | |
url(r'^plugin_move_last/$', self.plugin_move_last, name='cmsplugin_move_last'), | |
] | |
@classmethod | |
def get_extra_global_plugin_menu_items(cls, request, plugin): | |
return [ | |
PluginMenuItem( | |
_("Move to first position"), | |
reverse("admin:cmsplugin_move_first"), | |
data={'plugin_id': plugin.pk, 'csrfmiddlewaretoken': get_token(request)}, | |
), | |
PluginMenuItem( | |
_("Move to last position"), | |
reverse("admin:cmsplugin_move_last"), | |
data={'plugin_id': plugin.pk, 'csrfmiddlewaretoken': get_token(request)}, | |
) | |
] | |
def plugin_move_first(self, request): | |
return self._plugin_move_to(request, 'first') | |
def plugin_move_last(self, request): | |
return self._plugin_move_to(request, 'last') | |
def _plugin_move_to(self, request, position='first'): | |
if not request.user.is_staff: | |
return HttpResponseForbidden("not enough privileges") | |
if not 'plugin_id' in request.POST: | |
return HttpResponseBadRequest("plugin_id POST parameter missing.") | |
plugin = None | |
if 'plugin_id' in request.POST: | |
pk = request.POST['plugin_id'] | |
try: | |
plugin = CMSPlugin.objects.get(pk=pk) | |
except CMSPlugin.DoesNotExist: | |
return HttpResponseBadRequest("plugin with id %s not found." % pk) | |
# do it! | |
base_qs = CMSPlugin.objects.filter( | |
placeholder=plugin.placeholder, | |
parent=plugin.parent, | |
) | |
old_position = plugin.position | |
if position == 'first': | |
new_position = 0 | |
else: | |
new_position = base_qs.count() - 1 | |
if new_position == old_position: | |
pass | |
if new_position > old_position: | |
update_qs = base_qs.filter(position__lte=new_position, position__gt=old_position) | |
update_qs.update(**{'position': F('position') - 1}) | |
if new_position < old_position: | |
update_qs = base_qs.filter(position__gte=new_position, position__lt=old_position) | |
update_qs.update(**{'position': F('position') + 1}) | |
plugin.position = new_position | |
plugin.save() | |
return HttpResponse('ok') |
hm. the treebeard does the tree, but as far as I see, the cms uses only position, for sorting on each level?
https://github.com/divio/django-cms/blob/develop/cms/admin/placeholderadmin.py#L932
and here https://github.com/divio/django-cms/blob/develop/cms/utils/plugins.py#L304, as in the cms admin and utils methods for ordering?
...as mentioned, it already works...but sure, treebeard and position will not be in sync (but this happens all the time anyway, for example when sorting by hand with drag and drop, in structure mode...)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
when working with Treebeard, you should use their API to do "low-level" stuff. Presumably this method is your friend:
https://django-treebeard.readthedocs.io/en/latest/api.html#treebeard.models.Node.move