Example #1
0
 def get_related_objects(self, flatten=False):
     """
     Returns all objects related to the current.
     """
     collector = NestedObjects(using='default')
     collector.collect([self])
     if flatten:
         return list(utils.flatten(collector.nested()))
     return collector.nested()
def delete_survey(request, sid):
    survey = get_object_or_404(Engagement_Survey, id=sid)
    form = Delete_Eng_Survey_Form(instance=survey)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([survey])
    rels = collector.nested()

    if request.method == 'POST':
        if 'id' in request.POST and str(survey.id) == request.POST['id']:
            form = Delete_Eng_Survey_Form(request.POST, instance=survey)
            if form.is_valid():
                survey.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Survey and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('survey'))
    add_breadcrumb(title="Delete Survey", top_level=False, request=request)
    return render(request, 'defectDojo-engagement-survey/delete_survey.html', {
        'survey': survey,
        'form': form,
        'rels': rels,
    })
Example #3
0
def viewmap_delete_page(request, vsid):
    page = get_object_or_404(Page, pk=vsid)
    uim = page.uimodel

    if uim.is_frozen:
        return render(request, 'mcms/uimodels/frozen.html', dict(uimodel=uim))

    collector = NestedObjects(using='default')
    collector.collect([page])
    to_delete = collector.nested()

    if request.method == 'POST':
        page.delete()

        return HttpResponseRedirect(reverse('mcms:uimodels:edit_viewmap',
                                    kwargs={'vmid': page.viewmap.id}))

    opts = page._meta
    object_name = force_unicode(opts.verbose_name)
    title = ('Are you sure?')

    context = {
        'title': title,
        'object_name': object_name,
        'object': page,
        'deleted_objects': to_delete,
        'opts': opts,
        'app_label': opts.app_label,
    }

    return TemplateResponse(
        request,
        'mcms/uimodels/delete_confirmation.html', context, current_app='Test')
Example #4
0
def get_deleted_objects(obj, user):
    """
    Find all objects related to ``obj`` that should also be deleted. 

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.
    
    Copied and updated from django.contrib.admin.util for front end display.

    """
    using = router.db_for_write(obj.__class__)
    collector = NestedObjects(using=using)
    collector.collect([obj])
    perms_needed = set()

    def format_callback(obj):
        opts = obj._meta

        if hasattr(obj, "get_absolute_url"):
            url = obj.get_absolute_url()
            p = "%s.%s" % (opts.app_label, opts.get_delete_permission())
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            return mark_safe(u'%s: <a href="%s">%s</a>' % (escape(capfirst(opts.verbose_name)), url, escape(obj)))
        else:
            # no link
            return u"%s: %s" % (capfirst(opts.verbose_name), force_unicode(obj))

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]

    return to_delete, perms_needed, protected
Example #5
0
def delete_user(request, uid):
    user = get_object_or_404(Dojo_User, id=uid)
    form = DeleteUserForm(instance=user)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([user])
    rels = collector.nested()

    if user.id == request.user.id:
        messages.add_message(request,
                             messages.ERROR,
                             'You may not delete yourself.',
                             extra_tags='alert-danger')
        return HttpResponseRedirect(reverse('edit_user', args=(user.id,)))

    if request.method == 'POST':
        if 'id' in request.POST and str(user.id) == request.POST['id']:
            form = DeleteUserForm(request.POST, instance=user)
            if form.is_valid():
                user.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'User and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('users'))
    add_breadcrumb(title="Delete User", top_level=False, request=request)
    return render(request, 'dojo/delete_user.html',
                  {'to_delete': user,
                   'form': form,
                   'rels': rels,
                   })
Example #6
0
 def get_context_data(self, **kwargs):
     context = super(EmplacementDelete, self).get_context_data(**kwargs)
     collector = NestedObjects(using=DEFAULT_DB_ALIAS)
     collector.collect([context['object']])
     deleted_elements = collector.nested()
     context['deleted_elements'] = deleted_in_str(deleted_elements)
     return context
Example #7
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([engagement])
    rels = collector.nested()

    if request.method == 'POST':
        if 'id' in request.POST and str(engagement.id) == request.POST['id']:
            form = DeleteEngagementForm(request.POST, instance=engagement)
            if form.is_valid():
                engagement.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Engagement and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_product', args=(product.id,)))

    add_breadcrumb(parent=engagement, title="Delete", top_level=False, request=request)

    return render(request, 'dojo/delete_engagement.html',
                  {'engagement': engagement,
                   'form': form,
                   'rels': rels,
                   })
Example #8
0
def deletion_tree(obj):
    ''' Return a list of all nested objects that will be deleted '''
    collector = NestedObjects(using=obj._state.db)
    collector.collect([obj])
    def format_callback(obj):
        return u'%s: %s' % (force_text(obj._meta.verbose_name), force_text(obj))
    return collector.nested(format_callback)
def delete_survey(request, sid):
    survey = get_object_or_404(Engagement_Survey, id=sid)
    form = Delete_Eng_Survey_Form(instance=survey)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([survey])
    rels = collector.nested()

    if request.method == 'POST':
        if 'id' in request.POST and str(survey.id) == request.POST['id']:
            form = Delete_Eng_Survey_Form(request.POST, instance=survey)
            if form.is_valid():
                survey.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Survey and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('survey'))
    add_breadcrumb(title="Delete Survey", top_level=False, request=request)
    return render(request, 'defectDojo-engagement-survey/delete_survey.html',
                  {'survey': survey,
                   'form': form,
                   'rels': rels,
                   })
Example #10
0
 def get_context_data(self, *args, **kwargs):
     context = super(DeleteView, self).get_context_data(*args, **kwargs)
     using = router.db_for_write(self.model)
     collector = NestedObjects(using=using)
     collector.collect([self.object])
     context["related_objects"] = collector.nested()
     return context
Example #11
0
def ui_model_delete_device(request, umdid):
    uim_device = UIModelDevice.objects.get(id=umdid)

    if uim_device.uimodel.is_frozen:
        return render(request, 'mcms/uimodels/frozen.html',
                      dict(uimodel=uim_device.uimodel))

    collector = NestedObjects(using='default')
    collector.collect([uim_device, ])
    to_delete = collector.nested()

    if request.method == 'POST':  # The user has already confirmed the delete.
        uim_device.delete()

        return HttpResponseRedirect(
            reverse('mcms:uimodels:details', kwargs={
                'mid': uim_device.uimodel.id}))

    opts = uim_device._meta
    object_name = force_unicode(opts.verbose_name)
    title = ('Are you sure?')

    context = {
        'title': title,
        'object_name': object_name,
        'object': uim_device,
        'deleted_objects': to_delete,
        'opts': opts,
        'app_label': opts.app_label,
    }

    return TemplateResponse(
        request,
        'mcms/uimodels/delete_confirmation.html', context, current_app='Test')
Example #12
0
def delete_user(request, uid):
    user = get_object_or_404(Dojo_User, id=uid)
    form = DeleteUserForm(instance=user)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([user])
    rels = collector.nested()

    if user.id == request.user.id:
        messages.add_message(request,
                             messages.ERROR,
                             'You may not delete yourself.',
                             extra_tags='alert-danger')
        return HttpResponseRedirect(reverse('edit_user', args=(user.id, )))

    if request.method == 'POST':
        if 'id' in request.POST and str(user.id) == request.POST['id']:
            form = DeleteUserForm(request.POST, instance=user)
            if form.is_valid():
                user.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'User and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('users'))
    add_breadcrumb(title="Delete User", top_level=False, request=request)
    return render(request, 'dojo/delete_user.html', {
        'to_delete': user,
        'form': form,
        'rels': rels,
    })
Example #13
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    from django.contrib.admin.util import NestedObjects
    from django.db import DEFAULT_DB_ALIAS

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([engagement])
    rels = collector.nested()

    if request.method == 'POST':
        if 'id' in request.POST and str(engagement.id) == request.POST['id']:
            form = DeleteEngagementForm(request.POST, instance=engagement)
            if form.is_valid():
                del engagement.tags
                engagement.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Engagement and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(
                    reverse('view_product', args=(product.id, )))

    add_breadcrumb(parent=engagement,
                   title="Delete",
                   top_level=False,
                   request=request)

    return render(request, 'dojo/delete_engagement.html', {
        'engagement': engagement,
        'form': form,
        'rels': rels,
    })
Example #14
0
 def get_context_data(self, **kwargs):
     context = super(OrganizationDelete, self).get_context_data(**kwargs)
     collector = NestedObjects(using=DEFAULT_DB_ALIAS)
     collector.collect([context['object']])
     deleted_elements = collector.nested()
     context['deleted_elements'] = deleted_in_str(deleted_elements)
     context['title'] = _("Organization")
     context['model'] = "organization"
     return context
Example #15
0
def list_deleted_objects(obj):
    model = obj.__class__
    def format_callback(item):
        return u'%s: %s' % (item._meta.verbose_name.capitalize(), force_unicode(item))

    collector = NestedObjects(using=router.db_for_write(model))
    collector.collect(model.objects.filter(id=obj.id))
    to_delete = collector.nested(format_callback)

    return {'to_delete': to_delete}
Example #16
0
def delete_bastard(obj):
    """
    Delete the bastard obj, user or subscriber.
    Don't delete if cascade will delete a protected object, in this case alert.
    """
    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([obj])

    def candelete(item):
        if isinstance(item, Iterable):
            return all([candelete(i) for i in item])
        elif type(item) in PROTECTED_CLASSES:
            print("%s not deleted because has %s" % (obj, item))
            return False
        else:
            return True

    if candelete(collector.nested()):
        print("Deleting %s and %s" % (obj, collector.nested()))
        obj.delete()
def make_mobile_numbers_unique(users):
    for user in users:
        collector = NestedObjects(using=DEFAULT_DB_ALIAS)
        collector.collect([user])
        items = collector.nested()
        for item in items:
            if isinstance(item, User):
                continue
            else:
                unique_instances = set([str(instance.__class__.__name__) for instance in item])
                if len(unique_instances) == 1:
                    pass
def make_mobile_numbers_unique(users):
    for user in users:
        collector = NestedObjects(using=DEFAULT_DB_ALIAS)
        collector.collect([user])
        items = collector.nested()
        for item in items:
            if isinstance(item, User):
                continue
            else:
                unique_instances = set(
                    [str(instance.__class__.__name__) for instance in item])
                if len(unique_instances) == 1:
                    pass
Example #19
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """

    def setUp(self):
        self.n = NestedObjects()
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEquals(self.n.nested(lambda obj: obj.num), target)

    def _add(self, obj, parent=None):
        # don't bother providing the extra args that NestedObjects ignores
        self.n.add(None, None, obj, None, parent)

    def test_unrelated_roots(self):
        self._add(self.objs[0])
        self._add(self.objs[1])
        self._add(self.objs[2], self.objs[1])

        self._check([0, 1, [2]])

    def test_siblings(self):
        self._add(self.objs[0])
        self._add(self.objs[1], self.objs[0])
        self._add(self.objs[2], self.objs[0])

        self._check([0, [1, 2]])

    def test_duplicate_instances(self):
        self._add(self.objs[0])
        self._add(self.objs[1])
        dupe = Count.objects.get(num=1)
        self._add(dupe, self.objs[0])

        self._check([0, 1])

    def test_non_added_parent(self):
        self._add(self.objs[0], self.objs[1])

        self._check([0])

    def test_cyclic(self):
        self._add(self.objs[0], self.objs[2])
        self._add(self.objs[1], self.objs[0])
        self._add(self.objs[2], self.objs[1])
        self._add(self.objs[0], self.objs[2])

        self._check([0, [1, [2]]])
Example #20
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """

    def setUp(self):
        self.n = NestedObjects(using=DEFAULT_DB_ALIAS)
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEqual(self.n.nested(lambda obj: obj.num), target)

    def _connect(self, i, j):
        self.objs[i].parent = self.objs[j]
        self.objs[i].save()

    def _collect(self, *indices):
        self.n.collect([self.objs[i] for i in indices])

    def test_unrelated_roots(self):
        self._connect(2, 1)
        self._collect(0)
        self._collect(1)
        self._check([0, 1, [2]])

    def test_siblings(self):
        self._connect(1, 0)
        self._connect(2, 0)
        self._collect(0)
        self._check([0, [1, 2]])

    def test_non_added_parent(self):
        self._connect(0, 1)
        self._collect(0)
        self._check([0])

    def test_cyclic(self):
        self._connect(0, 2)
        self._connect(1, 0)
        self._connect(2, 1)
        self._collect(0)
        self._check([0, [1, [2]]])

    def test_queries(self):
        self._connect(1, 0)
        self._connect(2, 0)
        # 1 query to fetch all children of 0 (1 and 2)
        # 1 query to fetch all children of 1 and 2 (none)
        # Should not require additional queries to populate the nested graph.
        self.assertNumQueries(2, self._collect, 0)
Example #21
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """
    def setUp(self):
        self.n = NestedObjects(using=DEFAULT_DB_ALIAS)
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEqual(self.n.nested(lambda obj: obj.num), target)

    def _connect(self, i, j):
        self.objs[i].parent = self.objs[j]
        self.objs[i].save()

    def _collect(self, *indices):
        self.n.collect([self.objs[i] for i in indices])

    def test_unrelated_roots(self):
        self._connect(2, 1)
        self._collect(0)
        self._collect(1)
        self._check([0, 1, [2]])

    def test_siblings(self):
        self._connect(1, 0)
        self._connect(2, 0)
        self._collect(0)
        self._check([0, [1, 2]])

    def test_non_added_parent(self):
        self._connect(0, 1)
        self._collect(0)
        self._check([0])

    def test_cyclic(self):
        self._connect(0, 2)
        self._connect(1, 0)
        self._connect(2, 1)
        self._collect(0)
        self._check([0, [1, [2]]])

    def test_queries(self):
        self._connect(1, 0)
        self._connect(2, 0)
        # 1 query to fetch all children of 0 (1 and 2)
        # 1 query to fetch all children of 1 and 2 (none)
        # Should not require additional queries to populate the nested graph.
        self.assertNumQueries(2, self._collect, 0)
Example #22
0
def related_objects(obj):
    """ Return a generator to the objects that would be deleted if we delete "obj" (excluding obj) """

    collector = NestedObjects(using=router.db_for_write(obj))
    collector.collect([obj])

    def flatten(elem):
        if isinstance(elem, list):
            return itertools.chain.from_iterable(map(flatten, elem))
        elif obj != elem:
            return (elem,)
        return ()

    return flatten(collector.nested())
Example #23
0
def related_objects(obj):
    """ Return a generator to the objects that would be deleted if we delete "obj" (excluding obj) """

    collector = NestedObjects(using=router.db_for_write(obj))
    collector.collect([obj])

    def flatten(elem):
        if isinstance(elem, list):
            return itertools.chain.from_iterable(map(flatten, elem))
        elif obj != elem:
            return (elem, )
        return ()

    return flatten(collector.nested())
Example #24
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """
    def setUp(self):
        self.n = NestedObjects()
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEquals(self.n.nested(lambda obj: obj.num), target)

    def _add(self, obj, parent=None):
        # don't bother providing the extra args that NestedObjects ignores
        self.n.add(None, None, obj, None, parent)

    def test_unrelated_roots(self):
        self._add(self.objs[0])
        self._add(self.objs[1])
        self._add(self.objs[2], self.objs[1])

        self._check([0, 1, [2]])

    def test_siblings(self):
        self._add(self.objs[0])
        self._add(self.objs[1], self.objs[0])
        self._add(self.objs[2], self.objs[0])

        self._check([0, [1, 2]])

    def test_duplicate_instances(self):
        self._add(self.objs[0])
        self._add(self.objs[1])
        dupe = Count.objects.get(num=1)
        self._add(dupe, self.objs[0])

        self._check([0, 1])

    def test_non_added_parent(self):
        self._add(self.objs[0], self.objs[1])

        self._check([0])

    def test_cyclic(self):
        self._add(self.objs[0], self.objs[2])
        self._add(self.objs[1], self.objs[0])
        self._add(self.objs[2], self.objs[1])
        self._add(self.objs[0], self.objs[2])

        self._check([0, [1, [2]]])
Example #25
0
def _get_deleted_objects(objs):
    """
    Slightly simplified version of the function used in the standard admin
    """

    if len(objs) == 0:
        return []

    collector = NestedObjects(using=router.db_for_write(objs[0]))
    collector.collect(objs)

    def format_callback(obj):
        return '%s: %s' % (obj.__class__.__name__, unicode(obj))

    return collector.nested(format_callback)
Example #26
0
def get_deleted_objects(obj):
    """
    Find all objects related to ``objs`` that should also be
    deleted. ``objs`` should be an iterable of objects.

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.
    """

    collector = NestedObjects()

    obj._collect_sub_objects(collector)

    to_delete = collector.nested(_format_callback)

    return to_delete
Example #27
0
def get_deleted_objects(objs, opts, user, admin_site, using):
    collector = NestedObjects(using=using)
    collector.collect(objs)
    perms_needed = set()
    
    def clean_empty(objects):
        cleaned = []
        for obj in objects:
            if isinstance(obj, list):
                cleaned.append(clean_empty(obj))
            elif obj != '':
                cleaned.append(obj)
        return cleaned if cleaned else '"Hidden objects"'
    
    def format_callback(obj):
        has_admin = admin_site._registry.get(obj.__class__, False)
        opts = obj._meta
        if has_admin:
            if getattr(has_admin, 'deletable_objects_excluded', False):
                return ''
            admin_url = reverse('%s:%s_%s_change'
                                % (admin_site.name,
                                   opts.app_label,
                                   opts.object_name.lower()),
                                None, (quote(obj._get_pk_val()),))
            p = '%s.%s' % (opts.app_label,
                           opts.get_delete_permission())
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            # NOTE: Define as unicode for avoid errors when obj
            # representation contains non-ascii chars
            return format_html(u'{0}: <a href="{1}">{2}</a>',
                               capfirst(opts.verbose_name),
                               admin_url,
                               obj)
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return u'%s: %s' % (capfirst(opts.verbose_name),
                                force_text(obj))
    to_delete = collector.nested(format_callback)
    to_delete = clean_empty(to_delete)
    protected = [format_callback(obj) for obj in collector.protected]
    return to_delete, perms_needed, protected
Example #28
0
    def response(self, request, username, project_slug, member_username):
        membership = get_object_or_404(
            Membership.objects.select_related('project', 'member'),
            project__slug=project_slug,
            project__author__username=username,
            member__username=member_username)\

        member = membership.member
        project = membership.project

        if project.author == member:
            messages.warning(
                request, _("Project owner's membership cannot be "
                           "removed."))
            return redirect(project.get_members_url())
        collector = NestedObjects()
        membership._collect_sub_objects(collector)
        form = MembershipDeleteForm(request.POST or None)
        perms_to_delete = UserObjectPermission.objects.filter(
            user=member,
            content_type=ContentType.objects.get_for_model(project),
            object_pk=project.id)

        if request.method == 'POST':
            # Confirm removal
            if form.is_valid() and project.author != member:
                msg = _("Membership removed")
                messages.success(request, msg)
                membership.delete()
                perms_to_delete.delete()
                return redirect(project.get_members_url())
            else:
                msg = _("Couldn't remove membership")
                messages.error(request, msg)
                if project.author == member:
                    msg = _("Project's author cannot be removed")
                    messages.error(request, msg)
        context = {
            'project': project,
            'membership': membership,
            'form': form,
            'to_delete': collector.nested(),
            'member_perms': perms_to_delete,
        }
        return context
Example #29
0
def get_deleted_objects(objs):
    from django.contrib.admin.util import NestedObjects
    from django.utils.text import capfirst
    from django.utils.encoding import force_unicode

    def format_callback(obj):
        opts = obj._meta

        # Don't display link to edit, because it either has no
        # admin or is edited inline.
        return u'%s: %s' % (capfirst(opts.verbose_name),
                            force_unicode(obj))

    collector = NestedObjects(using='default')  # or specific database
#    collector = NestedObjects(using=using)
    collector.collect(objs)

    return collector.nested(format_callback)
Example #30
0
def collect_backlinks(model_instance):
    from django.contrib.admin.util import NestedObjects
    collector = NestedObjects(using='scenario_db')  # or specific database
    collector.collect([model_instance])
    dependants = collector.nested()  # fun fact: spelling differs between America and Brittain
    print("Found related models:", dependants)
    links = {}
    if len(dependants[1:]):
        for direct_reference in dependants[1:][0]:  # only iterates over the top level
            if not isinstance(direct_reference, list) and not isinstance(direct_reference, RelationalPoint):  # Points are obvious, don't include them
                name = direct_reference.__class__.__name__
                try:  # not everything has a name attr
                    links[str(direct_reference)] = '/setup/%s/%i/' % (name, direct_reference.pk)
                except:
                    links['%s:%i' % (name, direct_reference.pk)] = \
                        '/setup/%s/%i/' % (name, direct_reference.pk)
    print(links)
    return links
Example #31
0
def get_deleted_objects(objs, user):
    """
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogeneous iterable of objects (e.g. a QuerySet).

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.

    Copied and updated from django.contrib.admin.utils for front end display.
    """
    using = router.db_for_write(objs[0].__class__)
    collector = NestedObjects(using=using)
    collector.collect(objs)
    perms_needed = set()

    def format_callback(obj):
        opts = obj._meta

        no_edit_link = '%s: %s' % (capfirst(opts.verbose_name),
                                   force_text(obj))

        p = '%s.%s' % (opts.app_label,
                           get_permission_codename('delete', opts))
        if not user.has_perm(p):
            perms_needed.add(opts.verbose_name)
                
        if hasattr(obj, 'get_absolute_url'):
            url = obj.get_absolute_url()
            # Display a link to the admin page.
            return format_html('{}: <a href="{}">{}</a>',
                               capfirst(opts.verbose_name),
                               url,
                               obj)
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return no_edit_link

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]

    return to_delete, collector.model_count, perms_needed, protected
Example #32
0
def get_deleted_objects(objs, opts, user, admin_site, using):
	"""
	Find all objects related to ``objs`` that should also be deleted. ``objs``
	must be a homogenous iterable of objects (e.g. a QuerySet).

	Returns a nested list of strings suitable for display in the
	template with the ``unordered_list`` filter.

	"""
	collector = NestedObjects(using=using)
	collector.collect(objs)
	perms_needed = set()

	def format_callback(obj):
		has_admin = obj.__class__ in admin_site._registry
		opts = obj._meta

		if has_admin:
			admin_url = reverse('%s_%s_edit'
								% (
								   opts.app_label,
								   opts.object_name.lower()),
								None, (quote(obj._get_pk_val()),))
			p = '%s_%s_delete' % (opts.app_label,opts.object_name.lower())
			if not user.has_perm(p):
				perms_needed.add(opts.verbose_name)
			# Display a link to the admin page.
			return format_html(u'{0}: <a href="{1}">{2}</a>',
							   capfirst(opts.verbose_name),
							   admin_url,
							   obj)
		else:
			# Don't display link to edit, because it either has no
			# admin or is edited inline.
			return '%s: %s' % (capfirst(opts.verbose_name),
								force_text(obj))

	to_delete = collector.nested(format_callback)

	protected = [format_callback(obj) for obj in collector.protected]

	return to_delete, perms_needed, protected
Example #33
0
def reportwhatwillbedeleted(request, report):
    if not request.user.is_authenticated() or not hasPermission(
            request.user, 'moderate_reports'):
        raise PermissionDenied()
    context = ajaxContext(request)
    # Get the report
    report = get_object_or_404(models.Report,
                               pk=report,
                               i_status=models.Report.get_i(
                                   'status', 'Pending'))
    # Get the reported thing
    queryset = report.reported_thing_collection.queryset
    thing = get_object_or_404(queryset, pk=report.reported_thing_id)

    from django.contrib.admin.util import NestedObjects

    collector = NestedObjects(using='default')  # or specific database
    collector.collect([thing])
    context['report'] = report
    context['to_delete'] = collector.nested()
    return render(request, 'ajax/reportwhatwillbedeleted.html', context)
    def _collect_deleted_objects(self, obj):
        result = []
        try:
            # This is for Django up to 1.2
            from django.db.models.query_utils import CollectedObjects

            seen_objs = CollectedObjects()
            obj._collect_sub_objects(seen_objs)
            for cls, subobjs in seen_objs.iteritems():
                for subobj in subobjs.values():
                    result.append(subobj)
        except ImportError:
            # Django 1.3 solution, those imports needs to be here, because
            # otherwise they will fail on Django < 1.3.
            from django.contrib.admin.util import NestedObjects
            from django.db import router

            using = router.db_for_write(obj)
            collector = NestedObjects(using=using)
            collector.collect([obj])
            result = self._flatten(collector.nested())
        return result
Example #35
0
def get_related_objects( obj, to_update=DEFAULT_TO_UPDATE ):
    collector = NestedObjects( using=DEFAULT_DB_ALIAS )
    collector.collect( obj )
    perms_needed = set()

    def format_callback( o ):
        opts   = o._meta
        key    = '%s_%s' % ( opts.app_label, opts.object_name.lower() )
        to_delete =  key not in to_update

        try:
            admin_url = reverse( 'admin:%s_%s_change' % ( opts.app_label, opts.object_name.lower() ),
                                None, ( o._get_pk_val() ,) )
        except:
            return mark_safe( u'%s%s: %s%s' % ( '<strike>' if to_delete else '', capfirst( opts.verbose_name ), force_unicode( o ), '</strike>' if to_delete else '' ) )

        return mark_safe( u'%s%s: <a href="%s">%s</a>%s' %
                             ( '<strike>' if to_delete else '', escape( capfirst( opts.verbose_name ) ),
                              admin_url, escape( o ), '</strike>' if to_delete else '' ) )


    return collector.nested(format_callback)
Example #36
0
def get_deleted_objects(obj, user):
    """
    Find all objects related to ``obj`` that should also be deleted. 

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.
    
    Copied and updated from django.contrib.admin.util for front end display.

    """
    using = router.db_for_write(obj.__class__)
    collector = NestedObjects(using=using)
    collector.collect([obj])
    perms_needed = set()

    def format_callback(obj):
        opts = obj._meta

        if hasattr(obj, 'get_absolute_url'):
            url = obj.get_absolute_url()
            p = '%s.%s' % (opts.app_label,
                           opts.get_delete_permission())
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            return mark_safe(u'%s: <a href="%s">%s</a>' %
                             (escape(capfirst(opts.verbose_name)),
                              url,
                              escape(obj)))
        else:
            # no link
            return u'%s: %s' % (capfirst(opts.verbose_name),
                                force_unicode(obj))

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]

    return to_delete, perms_needed, protected
Example #37
0
def get_deleted_objects(objs, opts, user, admin_site, using):
    """
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogenous iterable of objects (e.g. a QuerySet).

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.

    """
    collector = NestedObjects(using=using)
    collector.collect(objs)
    perms_needed = set()

    def format_callback(obj):
        opts = obj._meta

        return '%s: %s' % (capfirst(opts.verbose_name), force_text(obj))

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]

    return to_delete, perms_needed, protected
Example #38
0
def get_deleted_objects(objs, opts, user, admin_site, using):
    """
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogenous iterable of objects (e.g. a QuerySet).

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.

    """
    collector = NestedObjects(using=using)
    collector.collect(objs)
    perms_needed = set()

    def format_callback(obj):
        opts = obj._meta

        return '%s: %s' % (capfirst(opts.verbose_name),
                           force_text(obj))

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]

    return to_delete, perms_needed, protected
Example #39
0
    def response(self, request, username, project_slug, name):
        team = get_object_or_404(
            Team.objects.select_related('group', 'project'),
            project__author__username=username,
            project__slug=project_slug, group__name=name)

        group, project = team.group, team.project

        collector = NestedObjects()
        team._collect_sub_objects(collector)
        form = TeamDeleteForm(request.POST or None)
        perms_to_delete = GroupObjectPermission.objects.filter(
            group = group,
            content_type = ContentType.objects.get_for_model(project),
            object_pk = project.id)

        if request.method == 'POST':
            # Confirm removal
            if form.is_valid():
                msg = _("Team removed")
                messages.success(request, msg)
                team.delete()
                perms_to_delete.delete()
                return redirect(project.get_teams_url())
            else:
                msg = _("Couldn't remove team")
                messages.error(request, msg)

        context = {
            'project': project,
            'team': team,
            'form': form,
            'to_delete': collector.nested(),
            'team_perms': perms_to_delete,
        }
        return context
Example #40
0
def delete_related_objects(modeladmin, request, queryset):
    """
    Action that deletes related objects for the selected items.

    This action first displays a confirmation page whichs shows all the
    deleteable objects, or, if the user has no permission one of the related
    childs (foreignkeys), a "permission denied" message.

    Next, it deletes all related objects and redirects back to the change list.
    """
    opts = modeladmin.model._meta
    app_label = opts.app_label

    # Check that the user has delete permission for the actual model
    if not modeladmin.has_delete_permission(request):
        raise PermissionDenied

    using = router.db_for_write(modeladmin.model)

    first_level_related_objects = []
    first_level_related_objects_by_type = defaultdict(list)
    collector = NestedObjects(using=using)
    collector.collect(queryset)
    for base_object_or_related_list in collector.nested():
        if type(base_object_or_related_list) is not list:
            # If it's not a list, it's a base object. Skip it.
            continue
        for obj in base_object_or_related_list:
            if type(obj) is list:
                # A list here contains related objects for the previous
                # element. We can skip it since delete() on the first
                # level of related objects will cascade.
                continue
            else:
                first_level_related_objects.append(obj)
                first_level_related_objects_by_type[type(obj)].append(obj)

    deletable_objects = []
    model_count = defaultdict(int)
    perms_needed = set()
    protected = []
    # `get_deleted_objects()` fails when passed a heterogeneous list like
    # `first_level_related_objects`, so embark on this rigmarole to spoon-feed
    # it only homogeneous lists
    for homogeneous_list in first_level_related_objects_by_type.values():
        # Populate deletable_objects, a data structure of (string
        # representations of) all related objects that will also be deleted.
        deletable_objects_, model_count_, perms_needed_, protected_ = get_deleted_objects(
            homogeneous_list, opts, request.user, modeladmin.admin_site, using)
        # Combine the results with those from previous homogeneous lists
        deletable_objects.extend(deletable_objects_)
        for k, v in model_count_.iteritems():
            model_count[k] += v
        perms_needed.update(perms_needed_)
        protected.extend(protected_)

    # The user has already confirmed the deletion.
    # Do the deletion and return a None to display the change list view again.
    if request.POST.get('post'):
        if perms_needed:
            raise PermissionDenied
        n = 0
        with transaction.atomic(using):
            for obj in first_level_related_objects:
                obj_display = force_text(obj)
                modeladmin.log_deletion(request, obj, obj_display)
                obj.delete()
                n += 1
        modeladmin.message_user(
            request,
            _("Successfully deleted %(count)d related objects.") % {
                "count": n,
                "items": model_ngettext(modeladmin.opts, n)
            }, messages.SUCCESS)
        # Return None to display the change list page again.
        return None

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    if perms_needed or protected:
        title = _("Cannot delete %(name)s") % {"name": objects_name}
    else:
        title = _("Are you sure?")

    context = dict(
        modeladmin.admin_site.each_context(request),
        title=title,
        objects_name=objects_name,
        deletable_objects=[deletable_objects],
        model_count=dict(model_count).items(),
        queryset=queryset,
        perms_lacking=perms_needed,
        protected=protected,
        opts=opts,
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
    )

    request.current_app = modeladmin.admin_site.name

    # Display the confirmation page
    return TemplateResponse(request,
                            "delete_related_for_selected_confirmation.html",
                            context,
                            current_app=modeladmin.admin_site.name)
Example #41
0
def delete_related_objects(modeladmin, request, queryset):
    """
    Action that deletes related objects for the selected items.

    This action first displays a confirmation page whichs shows all the
    deleteable objects, or, if the user has no permission one of the related
    childs (foreignkeys), a "permission denied" message.

    Next, it deletes all related objects and redirects back to the change list.
    """
    opts = modeladmin.model._meta
    app_label = opts.app_label

    # Check that the user has delete permission for the actual model
    if not modeladmin.has_delete_permission(request):
        raise PermissionDenied

    using = router.db_for_write(modeladmin.model)

    first_level_related_objects = []
    collector = NestedObjects(using=using)
    collector.collect(queryset)
    for base_object_or_related_list in collector.nested():
        if type(base_object_or_related_list) is not list:
            # If it's not a list, it's a base object. Skip it.
            continue
        for obj in base_object_or_related_list:
            if type(obj) is list:
                # A list here contains related objects for the previous
                # element. We can skip it since delete() on the first
                # level of related objects will cascade.
                continue
            else:
                first_level_related_objects.append(obj)

    # Populate deletable_objects, a data structure of (string representations
    # of) all related objects that will also be deleted.
    deletable_objects, model_count, perms_needed, protected = get_deleted_objects(
        first_level_related_objects, opts, request.user,
        modeladmin.admin_site, using
    )

    # The user has already confirmed the deletion.
    # Do the deletion and return a None to display the change list view again.
    if request.POST.get('post'):
        if perms_needed:
            raise PermissionDenied
        n = 0
        with transaction.atomic(using):
            for obj in first_level_related_objects:
                obj_display = force_text(obj)
                modeladmin.log_deletion(request, obj, obj_display)
                obj.delete()
                n += 1
        modeladmin.message_user(
            request,
            _("Successfully deleted %(count)d related objects.") % {
                "count": n, "items": model_ngettext(modeladmin.opts, n)},
            messages.SUCCESS
        )
        # Return None to display the change list page again.
        return None

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    if perms_needed or protected:
        title = _("Cannot delete %(name)s") % {"name": objects_name}
    else:
        title = _("Are you sure?")

    context = dict(
        modeladmin.admin_site.each_context(request),
        title=title,
        objects_name=objects_name,
        deletable_objects=[deletable_objects],
        model_count=dict(model_count).items(),
        queryset=queryset,
        perms_lacking=perms_needed,
        protected=protected,
        opts=opts,
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
    )

    request.current_app = modeladmin.admin_site.name

    # Display the confirmation page
    return TemplateResponse(
        request, "delete_related_for_selected_confirmation.html",
        context, current_app=modeladmin.admin_site.name)
Example #42
0
    def get_deleted_objects(self, objs, opts, request, using):
        """
        Find all objects related to ``objs`` that should also be deleted. ``objs``
        must be a homogenous iterable of objects (e.g. a QuerySet).
    
        Returns a nested list of strings suitable for display in the
        template with the ``unordered_list`` filter.
        
        Copied from django.contrib.admin.util.get_deleted_objects and
        extended to override delete permissions to take the object's
        uploader into account, by allowing deletion if has_delete_permission()
        returns True.
        """

        from django.contrib.admin.util import NestedObjects
        collector = NestedObjects(using=using)
        collector.collect(objs)
        perms_needed = set()
    
        def format_callback(obj):
            has_admin = obj.__class__ in self.admin_site._registry
            opts = obj._meta

            from django.utils.html import escape
            from django.utils.safestring import mark_safe
            from django.utils.text import capfirst
            from django.core.urlresolvers import reverse
    
            if has_admin:
                from django.contrib.admin.util import quote
                admin_url = reverse('%s:%s_%s_change'
                                    % (self.admin_site.name,
                                       opts.app_label,
                                       opts.object_name.lower()),
                                    None, (quote(obj._get_pk_val()),))
                p = '%s.%s' % (opts.app_label,
                               opts.get_delete_permission())
                
                if isinstance(obj, self.model):
                    if not self.has_delete_permission(request, obj):
                        perms_needed.add(opts.verbose_name)
                elif not request.user.has_perm(p):
                    perms_needed.add(opts.verbose_name)
                # Display a link to the admin page.

                return mark_safe(u'%s: <a href="%s">%s</a>' %
                                 (escape(capfirst(opts.verbose_name)),
                                  admin_url,
                                  escape(obj)))
            else:
                # Don't display link to edit, because it either has no
                # admin or is edited inline.
                from django.utils.encoding import force_unicode
                return u'%s: %s' % (capfirst(opts.verbose_name),
                                    force_unicode(obj))
    
        to_delete = collector.nested(format_callback)
    
        protected = [format_callback(obj) for obj in collector.protected]
    
        return to_delete, perms_needed, protected
Example #43
0
 def get_context_data(self, **kwargs):
     collector = NestedObjects(using=DEFAULT_DB_ALIAS)
     collector.collect([self.object])
     kwargs.setdefault('nested_objects', collector.nested())
     return super(TreeDeleteView, self).get_context_data(**kwargs)
Example #44
0
File: util.py Project: ernop/wfmu
def get_nested_objects(obj):
    from django.contrib.admin.util import NestedObjects
    collector = NestedObjects(using='default')
    collector.collect([obj])
    return collector.nested()
Example #45
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """
    def setUp(self):
        self.n = NestedObjects(using=DEFAULT_DB_ALIAS)
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEqual(self.n.nested(lambda obj: obj.num), target)

    def _connect(self, i, j):
        self.objs[i].parent = self.objs[j]
        self.objs[i].save()

    def _collect(self, *indices):
        self.n.collect([self.objs[i] for i in indices])

    def test_unrelated_roots(self):
        self._connect(2, 1)
        self._collect(0)
        self._collect(1)
        self._check([0, 1, [2]])

    def test_siblings(self):
        self._connect(1, 0)
        self._connect(2, 0)
        self._collect(0)
        self._check([0, [1, 2]])

    def test_non_added_parent(self):
        self._connect(0, 1)
        self._collect(0)
        self._check([0])

    def test_cyclic(self):
        self._connect(0, 2)
        self._connect(1, 0)
        self._connect(2, 1)
        self._collect(0)
        self._check([0, [1, [2]]])

    def test_queries(self):
        self._connect(1, 0)
        self._connect(2, 0)
        # 1 query to fetch all children of 0 (1 and 2)
        # 1 query to fetch all children of 1 and 2 (none)
        # Should not require additional queries to populate the nested graph.
        self.assertNumQueries(2, self._collect, 0)

    def test_on_delete_do_nothing(self):
        """
        Check that the nested collector doesn't query for DO_NOTHING objects.
        """
        n = NestedObjects(using=DEFAULT_DB_ALIAS)
        objs = [Event.objects.create()]
        EventGuide.objects.create(event=objs[0])
        with self.assertNumQueries(2):
            # One for Location, one for Guest, and no query for EventGuide
            n.collect(objs)
Example #46
0
class NestedObjectsTests(TestCase):
    """
    Tests for ``NestedObject`` utility collection.

    """
    def setUp(self):
        self.n = NestedObjects(using=DEFAULT_DB_ALIAS)
        self.objs = [Count.objects.create(num=i) for i in range(5)]

    def _check(self, target):
        self.assertEqual(self.n.nested(lambda obj: obj.num), target)

    def _connect(self, i, j):
        self.objs[i].parent = self.objs[j]
        self.objs[i].save()

    def _collect(self, *indices):
        self.n.collect([self.objs[i] for i in indices])

    def test_unrelated_roots(self):
        self._connect(2, 1)
        self._collect(0)
        self._collect(1)
        self._check([0, 1, [2]])

    def test_siblings(self):
        self._connect(1, 0)
        self._connect(2, 0)
        self._collect(0)
        self._check([0, [1, 2]])

    def test_non_added_parent(self):
        self._connect(0, 1)
        self._collect(0)
        self._check([0])

    def test_cyclic(self):
        self._connect(0, 2)
        self._connect(1, 0)
        self._connect(2, 1)
        self._collect(0)
        self._check([0, [1, [2]]])

    def test_queries(self):
        self._connect(1, 0)
        self._connect(2, 0)
        # 1 query to fetch all children of 0 (1 and 2)
        # 1 query to fetch all children of 1 and 2 (none)
        # Should not require additional queries to populate the nested graph.
        self.assertNumQueries(2, self._collect, 0)

    def test_on_delete_do_nothing(self):
        """
        Check that the nested collector doesn't query for DO_NOTHING objects.
        """
        n = NestedObjects(using=DEFAULT_DB_ALIAS)
        objs = [Event.objects.create()]
        EventGuide.objects.create(event=objs[0])
        with self.assertNumQueries(2):
            # One for Location, one for Guest, and no query for EventGuide
            n.collect(objs)
Example #47
0
def have_relations_with(obj):
    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([obj])
    return len(collector.nested()) > 1
Example #48
0
def get_dep_objects(instance, using=DEFAULT_DB_ALIAS):
    """
    Find all objects related to ``objs`` that should also be deleted. ``objs``
    must be a homogeneous iterable of objects (e.g. a QuerySet).

    Returns a nested list of strings suitable for display in the
    template with the ``unordered_list`` filter.

    """
    collector = NestedObjects(using=using)
    collector.collect([instance])

    def format_callback(obj):
        no_edit_link = '%s: %s' % (capfirst(force_text(obj._meta.verbose_name)),
                                   force_text(obj))
        return no_edit_link

    def format_callback2(obj):
        no_edit_link = '%s' % (capfirst(force_text(obj._meta.verbose_name)))
        return no_edit_link

    #ver_objs = collector.nested(format_callback)
    objects = collector.nested()
    # print objects

    deps = []

    try:
        for x in objects[1]:
            if type(x) is not list:
                deps.append(x)
    except:
        pass

    # obteniendo mensaje para eliminar

    msg_del = ''

    if deps:
        objs = []
        for p in deps:
            if not 'relationship' in force_text(p._meta.verbose_name):
                objs.append(
                    _(u'<br>%(class_name)s: "%(instance)s"') % {
                        'class_name': capfirst(force_text(p._meta.verbose_name)),
                        'instance': force_text(p) + ' (' + force_text(p.pk) + ')'}
                )
        params = {
            'class_name': capfirst(force_text(instance._meta.verbose_name)),
            'instance': force_text(instance),
            'related_objects': get_text_list(objs, _('and'))}
        msg = _("Deleting %(class_name)s %(instance)s would require deleting the following "
                "protected related objects: %(related_objects)s")
        msgx = _("Deleting the %(object_name)s '%(escaped_object)s' would require deleting the "
                "following protected related objects:")
        #raise ValidationError(force_text(msg), code='deleting_protected', params=params)
        #raise Exception(msg)
        # messages.success(self.request, (', ').join(deps)# )
        msg_del = force_text(msg % params)

        msg_delx = msgx % {
            'object_name': capfirst(force_text(instance._meta.verbose_name)),
            'escaped_object': get_text_list(objs, _('and'))}

    return deps, msg_del