Initial commit
This commit is contained in:
127
env/lib/python3.10/site-packages/treebeard/admin.py
vendored
Normal file
127
env/lib/python3.10/site-packages/treebeard/admin.py
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
"""Django admin support for treebeard"""
|
||||
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import admin, messages
|
||||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.urls import path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
from treebeard.exceptions import (InvalidPosition, MissingNodeOrderBy,
|
||||
InvalidMoveToDescendant, PathOverflow)
|
||||
from treebeard.al_tree import AL_Node
|
||||
|
||||
|
||||
class TreeAdmin(admin.ModelAdmin):
|
||||
"""Django Admin class for treebeard."""
|
||||
|
||||
change_list_template = 'admin/tree_change_list.html'
|
||||
|
||||
def get_queryset(self, request):
|
||||
if issubclass(self.model, AL_Node):
|
||||
# AL Trees return a list instead of a QuerySet for .get_tree()
|
||||
# So we're returning the regular .get_queryset cause we will use
|
||||
# the old admin
|
||||
return super().get_queryset(request)
|
||||
else:
|
||||
return self.model.get_tree()
|
||||
|
||||
def changelist_view(self, request, extra_context=None):
|
||||
if issubclass(self.model, AL_Node):
|
||||
# For AL trees, use the old admin display
|
||||
self.change_list_template = 'admin/tree_list.html'
|
||||
if extra_context is None:
|
||||
extra_context = {}
|
||||
request_context = any(
|
||||
map(
|
||||
lambda tmpl:
|
||||
tmpl.get('BACKEND', None) == 'django.template.backends.django.DjangoTemplates' and
|
||||
tmpl.get('APP_DIRS', False) and
|
||||
'django.template.context_processors.request' in tmpl.get('OPTIONS', {}).get('context_processors', []),
|
||||
settings.TEMPLATES
|
||||
)
|
||||
)
|
||||
lacks_request = ('request' not in extra_context and not request_context)
|
||||
if lacks_request:
|
||||
extra_context['request'] = request
|
||||
return super().changelist_view(request, extra_context)
|
||||
|
||||
def get_urls(self):
|
||||
"""
|
||||
Adds a url to move nodes to this admin
|
||||
"""
|
||||
urls = super().get_urls()
|
||||
from django.views.i18n import JavaScriptCatalog
|
||||
|
||||
jsi18n_url = path('jsi18n/',
|
||||
JavaScriptCatalog.as_view(packages=['treebeard']),
|
||||
name='javascript-catalog'
|
||||
)
|
||||
|
||||
new_urls = [
|
||||
path('move/', self.admin_site.admin_view(self.move_node), ),
|
||||
jsi18n_url,
|
||||
]
|
||||
return new_urls + urls
|
||||
|
||||
def get_node(self, node_id):
|
||||
return self.model.objects.get(pk=node_id)
|
||||
|
||||
def try_to_move_node(self, as_child, node, pos, request, target):
|
||||
try:
|
||||
node.move(target, pos=pos)
|
||||
# Call the save method on the (reloaded) node in order to trigger
|
||||
# possible signal handlers etc.
|
||||
node = self.get_node(node.pk)
|
||||
node.save()
|
||||
except (MissingNodeOrderBy, PathOverflow, InvalidMoveToDescendant,
|
||||
InvalidPosition):
|
||||
e = sys.exc_info()[1]
|
||||
# An error was raised while trying to move the node, then set an
|
||||
# error message and return 400, this will cause a reload on the
|
||||
# client to show the message
|
||||
messages.error(request,
|
||||
_('Exception raised while moving node: %s') % _(
|
||||
force_str(e)))
|
||||
return HttpResponseBadRequest('Exception raised during move')
|
||||
if as_child:
|
||||
msg = _('Moved node "%(node)s" as child of "%(other)s"')
|
||||
else:
|
||||
msg = _('Moved node "%(node)s" as sibling of "%(other)s"')
|
||||
messages.info(request, msg % {'node': node, 'other': target})
|
||||
return HttpResponse('OK')
|
||||
|
||||
def move_node(self, request):
|
||||
try:
|
||||
node_id = request.POST['node_id']
|
||||
target_id = request.POST['sibling_id']
|
||||
as_child = bool(int(request.POST.get('as_child', 0)))
|
||||
except (KeyError, ValueError):
|
||||
# Some parameters were missing return a BadRequest
|
||||
return HttpResponseBadRequest('Malformed POST params')
|
||||
|
||||
node = self.get_node(node_id)
|
||||
target = self.get_node(target_id)
|
||||
is_sorted = True if node.node_order_by else False
|
||||
|
||||
pos = {
|
||||
(True, True): 'sorted-child',
|
||||
(True, False): 'last-child',
|
||||
(False, True): 'sorted-sibling',
|
||||
(False, False): 'left',
|
||||
}[as_child, is_sorted]
|
||||
return self.try_to_move_node(as_child, node, pos, request, target)
|
||||
|
||||
|
||||
def admin_factory(form_class):
|
||||
"""Dynamically build a TreeAdmin subclass for the given form class.
|
||||
|
||||
:param form_class:
|
||||
:return: A TreeAdmin subclass.
|
||||
"""
|
||||
return type(
|
||||
form_class.__name__ + 'Admin',
|
||||
(TreeAdmin,),
|
||||
dict(form=form_class))
|
||||
Reference in New Issue
Block a user