/usr/lib/python2.7/dist-packages/mptt/admin.py is in python-django-mptt 0.8.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | from __future__ import unicode_literals
from django.conf import settings
from django.contrib.admin.actions import delete_selected
from django.contrib.admin.options import ModelAdmin
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _
from mptt.forms import MPTTAdminForm, TreeNodeChoiceField
from mptt.models import MPTTModel, TreeForeignKey
__all__ = ('MPTTModelAdmin', 'MPTTAdminForm')
IS_GRAPPELLI_INSTALLED = 'grappelli' in settings.INSTALLED_APPS
class MPTTModelAdmin(ModelAdmin):
"""
A basic admin class that displays tree items according to their position in
the tree. No extra editing functionality beyond what Django admin normally
offers.
"""
if IS_GRAPPELLI_INSTALLED:
change_list_template = 'admin/grappelli_mptt_change_list.html'
else:
change_list_template = 'admin/mptt_change_list.html'
form = MPTTAdminForm
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if issubclass(db_field.rel.to, MPTTModel) \
and not isinstance(db_field, TreeForeignKey) \
and db_field.name not in self.raw_id_fields:
db = kwargs.get('using')
limit_choices_to = db_field.get_limit_choices_to()
defaults = dict(
form_class=TreeNodeChoiceField,
queryset=db_field.rel.to._default_manager.using(
db).complex_filter(limit_choices_to),
required=False)
defaults.update(kwargs)
kwargs = defaults
return super(MPTTModelAdmin, self).formfield_for_foreignkey(
db_field, request, **kwargs)
def get_ordering(self, request):
"""
Changes the default ordering for changelists to tree-order.
"""
mptt_opts = self.model._mptt_meta
return self.ordering or (mptt_opts.tree_id_attr, mptt_opts.left_attr)
def delete_selected_tree(self, modeladmin, request, queryset):
"""
Deletes multiple instances and makes sure the MPTT fields get
recalculated properly. (Because merely doing a bulk delete doesn't
trigger the post_delete hooks.)
"""
# If this is True, the confirmation page has been displayed
if request.POST.get('post'):
n = 0
with queryset.model._tree_manager.delay_mptt_updates():
for obj in queryset:
if self.has_delete_permission(request, obj):
obj.delete()
n += 1
obj_display = force_text(obj)
self.log_deletion(request, obj, obj_display)
self.message_user(
request,
_('Successfully deleted %(count)d items.') % {'count': n})
# Return None to display the change list page again
return None
else:
# (ab)using the built-in action to display the confirmation page
return delete_selected(self, request, queryset)
def get_actions(self, request):
actions = super(MPTTModelAdmin, self).get_actions(request)
if 'delete_selected' in actions:
actions['delete_selected'] = (
self.delete_selected_tree,
'delete_selected',
_('Delete selected %(verbose_name_plural)s'))
return actions
|