Exemple #1
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)
Exemple #2
0
def delete_rule(request, tid):
    rule = get_object_or_404(Rule, pk=tid)
    form = DeleteRuleForm(instance=rule)

    if request.method == 'POST':
        print >> sys.stderr, 'id' in request.POST
        print >> sys.stderr, str(rule.id) == request.POST['id']
        print >> sys.stderr, str(rule.id) == request.POST['id']
        # if 'id' in request.POST and str(rule.id) == request.POST['id']:
        form = DeleteRuleForm(request.POST, instance=rule)
        print >> sys.stderr, form.is_valid()
        print >> sys.stderr, form.errors
        print >> sys.stderr, form.non_field_errors()
        print >> sys.stderr, 'id' in request.POST
        if form.is_valid():
            rule.delete()
            messages.add_message(request,
                                 messages.SUCCESS,
                                 'Rule deleted.',
                                 extra_tags='alert-success')
            return HttpResponseRedirect(reverse('rules'))

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

    add_breadcrumb(parent=rule, title="Delete", top_level=False, request=request)
    system_settings = System_Settings.objects.get()
    return render(request, 'dojo/delete_rule.html',
                  {'rule': rule,
                   'form': form,
                   'active_tab': 'findings',
                   'system_settings': system_settings,
                   'rels': rels,
                   })
Exemple #3
0
def find_all_related_objects(model):
    collector = NestedObjects(using="default")  # database name
    collector.collect([model])  # list of objects. Single one won't do
    objects = []
    for obj_set in collector.data.values():
        objects += obj_set
    return objects
 def hand_clean_DELETE(self):
     """
     We don't validate the 'DELETE' field itself because on
     templates it's not rendered using the field information, but
     just using a generic "deletion_field" of the InlineModelAdmin.
     """
     if self.cleaned_data.get(DELETION_FIELD_NAME, False):
         using = router.db_for_write(self._meta.model)
         collector = NestedObjects(using=using)
         if self.instance.pk is None:
             return
         collector.collect([self.instance])
         if collector.protected:
             objs = []
             for p in collector.protected:
                 objs.append(
                     # Translators: Model verbose name and instance representation,
                     # suitable to be an item in a list.
                     _('%(class_name)s %(instance)s') % {
                         'class_name': p._meta.verbose_name,
                         'instance': p
                     })
             params = {
                 'class_name': self._meta.model._meta.verbose_name,
                 'instance': self.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")
             raise ValidationError(msg,
                                   code='deleting_protected',
                                   params=params)
Exemple #5
0
def _cascade_soft_delete(inst_or_qs, using, keep_parents=False):
    """
    Return collector instance that has marked ArchiveMixin instances for
    archive (i.e. update) instead of actual delete.
    Arguments:
        inst_or_qs (models.Model or models.QuerySet): the instance(s) that
            are to be deleted.
        using (db connection/router): the db to delete from.
        keep_parents (bool): defaults to False.  Determine if cascade is true.
    Returns:
        models.deletion.Collector: this is a standard Collector instance but
            the ArchiveMixin instances are in the fields for update list.
    """
    if not isinstance(inst_or_qs, models.QuerySet):
        instances = [inst_or_qs]
    else:
        instances = inst_or_qs

    # The collector will iteratively crawl the relationships and
    # create a list of models and instances that are connected to
    # this instance.
    collector = NestedObjects(using=using)
    collector.collect(instances, keep_parents=keep_parents)
    if collector.protected:
        raise models.ProtectedError("Delete protected", collector.protected)
    collector.sort()

    return collector
Exemple #6
0
    def delete(self, cascade=True, **kwargs):
        if self.PREVENT_DELETE:
            raise DeleteNotPermitted()

        if cascade:
            collector = NestedObjects(using='default')
            collector.collect([self])
            field_updates = collector.field_updates
            for cls, to_update in field_updates.iteritems():
                for (field, value), instances in to_update.iteritems():
                    cls.objects.filter(
                        pk__in={o.pk for o in instances}
                    ).update(
                        **{field.attname: value}
                    )
            for klass, objs in collector.data.iteritems():
                try:
                    klass._meta.get_field('is_void')
                except models.FieldDoesNotExist:
                    pass
                else:
                    klass.objects.filter(pk__in={o.pk for o in objs}).update(
                        is_void=True
                    )
        else:
            self.is_void = True
            self.save()
        signals.post_delete.send(
            sender=self.__class__, instance=self
        )
Exemple #7
0
    def delete_sql_data(self):
        for model_class, queryset in get_querysets_to_dump(self.domain_name, []):
            collector = NestedObjects(using=queryset.db)
            collector.collect(queryset)
            collector.delete()

        self.assertEqual([], list(get_objects_to_dump(self.domain_name, [])))
Exemple #8
0
def delete_jira(request, tid):
    jira_instance = get_object_or_404(JIRA_Conf, pk=tid)
    # eng = test.engagement
    # TODO Make Form
    form = DeleteJIRAConfForm(instance=jira_instance)

    if request.method == 'POST':
        if 'id' in request.POST and str(jira_instance.id) == request.POST['id']:
            form = DeleteJIRAConfForm(request.POST, instance=jira_instance)
            if form.is_valid():
                jira_instance.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'JIRA Conf and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('jira'))

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

    add_breadcrumb(title="Delete", top_level=False, request=request)
    return render(request, 'dojo/delete_jira.html',
                  {'inst': jira_instance,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Exemple #9
0
def delete_user(request, uid):
    user = get_object_or_404(Dojo_User, id=uid)
    form = DeleteUserForm(instance=user)

    from django.contrib.admin.utils 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,
    })
Exemple #10
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_engagement', args=(eng.id,)))

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

    product_tab = Product_Tab(test.engagement.product.id, title="Delete Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/delete_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Exemple #11
0
    def get(self, request, *args, **kwargs):

        #pr = get_object_or_404(Problem, tournament=request.user.profile.tournament, id=id)

        objs = self.get_objects(request, *args, **kwargs)

        def format_callback(obj):
            #print("callbacked %s"%(capfirst(obj._meta.verbose_name),) )
            #
            if type(obj) == JurorGrade:
                return '%s' % (capfirst(obj._meta.verbose_name),)
            else:
                return '%s: %s' % (capfirst(obj._meta.verbose_name), obj)

        collector = NestedObjects(using='default')  # or specific database
        #collector.collect(objs)
        if type(objs) == list:
            to_delete = []
            for obj in objs:
                collector.collect([obj])
                to_delete.append(collector.nested(format_callback))
        else:
            collector.collect(objs)
            to_delete = collector.nested(format_callback)

        return render(request, "dashboard/delObjPreview.html", context={'objs': to_delete})
Exemple #12
0
 def hand_clean_DELETE(self):
     """
     We don't validate the 'DELETE' field itself because on
     templates it's not rendered using the field information.
     """
     if self.cleaned_data.get(DELETION_FIELD_NAME, False):
         using = router.db_for_write(self._meta.model)
         collector = NestedObjects(using=using)
         if self.instance._state.adding:
             return
         collector.collect([self.instance])
         if collector.protected:
             objs = []
             for p in collector.protected:
                 objs.append(
                     # Translators: Model verbose name and instance representation,
                     # suitable to be an item in a list.
                     _("{class_name} {instance}").format(
                         class_name=p._meta.verbose_name,
                         instance=p))
             msg = _(
                 "Deleting {class_name} {instance} would require "
                 "deleting the following protected related objects: "
                 "{related_objects}").format(
                     class_name=self._meta.model._meta.verbose_name,
                     instance=self.instance,
                     related_objects=get_text_list(objs, _("and")),
                 )
             raise ValidationError(msg, code="deleting_protected")
def delete_product(request, pid):
    product = get_object_or_404(Product, pk=pid)
    form = DeleteProductForm(instance=product)

    if request.method == 'POST':
        if 'id' in request.POST and str(product.id) == request.POST['id']:
            form = DeleteProductForm(request.POST, instance=product)
            if form.is_valid():
                if product.tags:
                    del product.tags
                product.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Product and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(event='other',
                                    title='Deletion of %s' % product.name,
                                    description='The product "%s" was deleted by %s' % (product.name, request.user),
                                    url=request.build_absolute_uri(reverse('product')),
                                    icon="exclamation-triangle")
                return HttpResponseRedirect(reverse('product'))

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

    product_tab = Product_Tab(pid, title="Product", tab="settings")
    return render(request, 'dojo/delete_product.html',
                  {'product': product,
                   'form': form,
                   'product_tab': product_tab,
                   'rels': rels,
                   })
def will_be_deleted_with(instance):
    """Get items that would be deleted along with model ``instance``.

    Pass in any Django model instance that you intend to delete and get
    an iterator of related objects that would also be deleted.

    Since this is implemented as a generator, if you want a list of
    items, you'll need to do ``list(will_be_deleted_with(instance))``.

    Args:
        instance: A Django ORM instance

    Returns:
        pairs: (model class, items of that class that will be deleted)

    """
    # XXX: Not sure why this import can't be moved to module scope.
    from django.contrib.admin.utils import NestedObjects
    # The collector returns a list of all objects in the database that
    # would be deleted if `obj` were deleted.
    collector = NestedObjects(using='default')
    collector.collect([instance])
    for cls, items_to_delete in collector.data.items():
        # XXX: Not sure the collector will ever include the original
        # XXX: instance, but this check was in the original version and
        # XXX: I don't have time to verify at the moment.
        if instance in items_to_delete:
            items_to_delete.remove(instance)
        if items_to_delete:
            yield cls, items_to_delete
Exemple #15
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

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

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

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_engagement', args=(eng.id,)))

    add_breadcrumb(parent=test, title="Delete", top_level=False, request=request)
    return render(request, 'dojo/delete_test.html',
                  {'test': test,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Exemple #16
0
def delete_group(request, gid):
    group = get_object_or_404(Dojo_Group, id=gid)
    form = DeleteGroupForm(instance=group)

    if request.method == 'POST':
        if 'id' in request.POST and str(group.id) == request.POST['id']:
            form = DeleteGroupForm(request.POST, instance=group)
            if form.is_valid():
                group.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Group and relationships successfully removed.',
                    extra_tags='alert-success')
                return HttpResponseRedirect(reverse('groups'))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([group])
    rels = collector.nested()
    add_breadcrumb(title="Delete Group", top_level=False, request=request)
    return render(request, 'dojo/delete_group.html', {
        'to_delete': group,
        'form': form,
        'rels': rels
    })
Exemple #17
0
def delete_engagement_presets(request, pid, eid):
    prod = get_object_or_404(Product, id=pid)
    preset = get_object_or_404(Engagement_Presets, id=eid)
    form = DeleteEngagementPresetsForm(instance=preset)

    if request.method == 'POST':
        if 'id' in request.POST:
            form = DeleteEngagementPresetsForm(request.POST, instance=preset)
            if form.is_valid():
                preset.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Engagement presets and engagement relationships removed.',
                    extra_tags='alert-success')
                return HttpResponseRedirect(
                    reverse('engagement_presets', args=(pid, )))

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

    product_tab = Product_Tab(pid,
                              title="Delete Engagement Preset",
                              tab="settings")
    return render(
        request, 'dojo/delete_presets.html', {
            'product': product,
            'form': form,
            'product_tab': product_tab,
            'rels': rels,
        })
    def _related_objects(self, using):
        """
        Method to get all objects with foreign key the relation with self instance
        Args:
            self
        Returns:
            List(): all related objects
        """
        using = using or router.db_for_write(self.__class__, instance=self)

        collector = NestedObjects(using=using)
        collector.collect([self])

        def parse_list(obj):
            """
            Parse to nested objects
            Args:
                obj: list instance or models object instance
            Returns:
                list(): list with objects
            """
            if isinstance(obj, list):
                array = []
                for item in obj:
                    array += parse_list(item)
                return array
            return [obj]

        colletion = parse_list(collector.nested())
        colletion.remove(self)

        return colletion
def delete_product(request, pid):
    product = get_object_or_404(Product, pk=pid)
    form = DeleteProductForm(instance=product)

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

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

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

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

    return render(request, 'dojo/delete_product.html',
                  {'product': product,
                   'form': form,
                   'rels': rels,
                   })
Exemple #20
0
def get_deleted_objects(objs, request):
    try:
        obj = objs[0]
    except IndexError:
        return [], {}, set(), []
    else:
        using = router.db_for_write(obj._meta.model)
    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), obj)
        perms_needed.add(opts.verbose_name)

        try:
            return format_html('{}: <a href="{}">{}</a>',
                               capfirst(opts.verbose_name),
                               obj.get_absolute_url(), obj)
        except AttributeError:
            return no_edit_link

    to_delete = collector.nested(format_callback)

    protected = [format_callback(obj) for obj in collector.protected]
    model_count = {
        model._meta.verbose_name_plural: len(objs)
        for model, objs in collector.model_objs.items()
    }

    return to_delete, model_count, perms_needed, protected
Exemple #21
0
def delete_endpoint(request, eid):
    endpoint = get_object_or_404(Endpoint, pk=eid)
    product = endpoint.product
    form = DeleteEndpointForm(instance=endpoint)

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

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

    if request.method == 'POST':
        if 'id' in request.POST and str(endpoint.id) == request.POST['id']:
            form = DeleteEndpointForm(request.POST, instance=endpoint)
            if form.is_valid():
                del endpoint.tags
                endpoint.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Endpoint and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_product', args=(product.id,)))
    add_breadcrumb(parent=endpoint, title="Delete", top_level=False, request=request)
    return render(request, 'dojo/delete_endpoint.html',
                  {'endpoint': endpoint,
                   'form': form,
                   'rels': rels,
                   })
Exemple #22
0
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        context['protected_objects'] = self.protected_objects

        collector = NestedObjects(using='default')
        collector.collect([self.object])
        to_be_deleted = collector.nested()

        def remove_unpublished(tree):
            filtered_tree = []
            for item in tree:
                if type(item) == list:
                    filtered_tree.append(remove_unpublished(item))

                elif type(item) == Page:
                    filtered_tree.append(item)

                elif issubclass(type(item), Block) and type(item) != Block:
                    if item.published:
                        filtered_tree.append(item)

                elif type(item) == Reference:
                    if item.containing_block.published:
                        filtered_tree.append(item)

            return filtered_tree

        context['to_be_deleted'] = remove_unpublished(to_be_deleted)

        return context
Exemple #23
0
def merge_users(user, user_uuid):
    existing_user, created = get_user_model().objects.get_or_create(
        uuid=user_uuid, defaults={'is_active': True})

    collector = NestedObjects(using='default')
    collector.collect([user])
    to_change_user = collector.nested()
    try:
        related_objects = to_change_user[1]
    except IndexError:
        related_objects = []
    for related_object in related_objects:
        if getattr(related_object, 'user', None) == user:
            related_object.user = existing_user
            related_object.save()
        if getattr(related_object, 'created_by', None) == user:
            related_object.created_by = existing_user
            related_object.save()

    for group in user.communication_groups.all():
        group.users.add(existing_user)
    if hasattr(existing_user, 'participant'):
        participant = existing_user.participant
        participant.delete()
    user.delete()
Exemple #24
0
    def delete(self, cascade=True, **kwargs):
        if self.PREVENT_DELETE:
            raise DeleteNotPermitted()

        if cascade:
            collector = NestedObjects(using='default')
            collector.collect([self])
            field_updates = collector.field_updates
            for cls, to_update in field_updates.iteritems():
                for (field, value), instances in to_update.iteritems():
                    cls.objects.filter(
                        pk__in={o.pk for o in instances}
                    ).update(
                        **{field.attname: value}
                    )
            for klass, objs in collector.data.iteritems():
                try:
                    klass._meta.get_field('is_void')
                except models.FieldDoesNotExist:
                    pass
                else:
                    klass.objects.filter(pk__in={o.pk for o in objs}).update(
                        is_void=True
                    )
        else:
            self.is_void = True
            self.save()
        signals.post_delete.send(
            sender=self.__class__, instance=self
        )
def delete_github(request, tid):
    github_instance = get_object_or_404(GITHUB_Conf, pk=tid)
    # eng = test.engagement
    # TODO Make Form
    form = DeleteGITHUBConfForm(instance=github_instance)

    if request.method == 'POST':
        if 'id' in request.POST and str(github_instance.id) == request.POST['id']:
            form = DeleteGITHUBConfForm(request.POST, instance=github_instance)
            if form.is_valid():
                github_instance.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Github Conf and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('github'))

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

    add_breadcrumb(title="Delete", top_level=False, request=request)
    return render(request, 'dojo/delete_github.html',
                  {'inst': github_instance,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Exemple #26
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    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_engagements", args=(product.id, )))

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

    product_tab = Product_Tab(product.id, title="Delete Engagement", tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request, 'dojo/delete_engagement.html', {
        'product_tab': product_tab,
        'engagement': engagement,
        'form': form,
        'rels': rels,
    })
Exemple #27
0
def delete_test(request, tid):
    test = get_object_or_404(Test, pk=tid)
    eng = test.engagement
    form = DeleteTestForm(instance=test)

    if request.method == 'POST':
        if 'id' in request.POST and str(test.id) == request.POST['id']:
            form = DeleteTestForm(request.POST, instance=test)
            if form.is_valid():
                del test.tags
                test.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Test and relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('view_engagement', args=(eng.id,)))

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

    product_tab = Product_Tab(test.engagement.product.id, title="Delete Test", tab="engagements")
    product_tab.setEngagement(test.engagement)
    return render(request, 'dojo/delete_test.html',
                  {'test': test,
                   'product_tab': product_tab,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
def delete_jira(request, tid):
    jira_instance = get_object_or_404(JIRA_Conf, pk=tid)
    # eng = test.engagement
    # TODO Make Form
    form = DeleteJIRAConfForm(instance=jira_instance)

    if request.method == 'POST':
        if 'id' in request.POST and str(jira_instance.id) == request.POST['id']:
            form = DeleteJIRAConfForm(request.POST, instance=jira_instance)
            if form.is_valid():
                jira_instance.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'JIRA Conf and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(event='other',
                                    title='Deletion of JIRA URL %s' % jira_instance.url,
                                    description='JIRA url "%s" was deleted by %s' % (jira_instance.url, request.user),
                                    url=request.build_absolute_uri(reverse('jira')),
                                    )
                return HttpResponseRedirect(reverse('jira'))

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

    add_breadcrumb(title="Delete", top_level=False, request=request)
    return render(request, 'dojo/delete_jira.html',
                  {'inst': jira_instance,
                   'form': form,
                   'rels': rels,
                   'deletable_objects': rels,
                   })
Exemple #29
0
class DeleteViewWithDependencies(FlagMixin, RulesRequiredMixin, AjaxTemplateMixin, DeleteView):
    success_message = "The objects are been deleted successfully"
    protected_template = None

    collector = None

    def get(self, request, *args, **kwargs):
        self.collector = NestedObjects(using="default")

        self.get_collect()
        self.post_collect()

        # If there is some protected objects, change the template
        if self.collector.protected:
            self.template_name = self.protected_template

        return super().get(request, *args, **kwargs)

    def get_collect(self):
        # Collect objects how will be deleted
        self.collector.collect([self.get_object()])

    def post_collect(self):
        pass

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["deletable_objects"] = self.collector.nested(format_callback)
        context["protected_objects"] = self.collector.protected
        return context

    def delete(self, request, *args, **kwargs):
        result = super().delete(request, *args, **kwargs)
        display_success_messages(request, _(self.success_message))
        return result
Exemple #30
0
    def get_deleted_objects(self, objs, request):
        # we override here to allow soft_delete, modified from
        # https://github.com/django/django/blob/master/django/contrib/admin/utils.py
        """
        Find all objects related to ``objs`` that should also be deleted. ``objs``
        must be a homogeneous iterable of objects (e.g. a QuerySet).
        Return a nested list of strings suitable for display in the
        template with the ``unordered_list`` filter.
        """
        try:
            obj = objs[0]
        except IndexError:
            return [], {}, set(), []
        else:
            using = router.db_for_write(obj._meta.model)
        collector = NestedObjects(using=using)
        collector.collect(objs)

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

        to_delete = collector.nested(format_callback)
        model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()}
        # we need to display count by model of the protected items too
        protected = [format_callback(obj) for obj in collector.protected]
        protected_model = {obj._meta.verbose_name_plural for obj in collector.protected}
        protected_model_count = dict(Counter(protected_model))
        # since we are only performing soft delete, we may soft delete the protected objects later
        return to_delete + protected, {**model_count, **protected_model_count}, set(), []
Exemple #31
0
def delete_product_type(request, ptid):
    product_type = get_object_or_404(Product_Type, pk=ptid)
    form = Delete_Product_TypeForm(instance=product_type)

    if request.method == 'POST':
        if 'id' in request.POST and str(product_type.id) == request.POST['id']:
            form = Delete_Product_TypeForm(request.POST, instance=product_type)
            if form.is_valid():
                product_type.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Product Type and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(
                    event='other',
                    title='Deletion of %s' % product_type.name,
                    no_users=True,
                    description='The product type "%s" was deleted by %s' %
                    (product_type.name, request.user),
                    url=request.build_absolute_uri(reverse('product_type')),
                    icon="exclamation-triangle")
                return HttpResponseRedirect(reverse('product_type'))

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

    add_breadcrumb(title="Delete Product Type",
                   top_level=False,
                   request=request)
    return render(request, 'dojo/delete_product_type.html', {
        'product_type': product_type,
        'form': form,
        'rels': rels,
    })
Exemple #32
0
def create_backup(request):
    _pk = request.POST.get('_id')

    # user object
    user_obj = User.objects.get(pk=_pk)

    # NestedObjects is admin contrib package which is used as a Collector subclass.
    collector = NestedObjects(using="default")  # database name

    # create an object of NestedObjects
    collector.collect([user_obj])

    # create a list of all objects of all tables with foreign keys
    objects = list(chain.from_iterable(collector.data.values()))

    # store a data in file
    with open("dbfiles/{}.json".format(user_obj.username), "w") as f:
        s = serializers.serialize("json",
                                  objects,
                                  use_natural_foreign_keys=True,
                                  use_natural_primary_keys=True,
                                  indent=4)

        # make all tables objects pks null
        # s = re.sub('"pk": [0-9]{1,5}', '"pk": null', s)
        f.write(s)

    data = {'msg': 'Backup Created Successfully'}
    return JsonResponse(data)
Exemple #33
0
 def hand_clean_DELETE(self):
     """
     We don't validate the 'DELETE' field itself because on
     templates it's not rendered using the field information, but
     just using a generic "deletion_field" of the InlineModelAdmin.
     """
     if self.cleaned_data.get(DELETION_FIELD_NAME, False):
         using = router.db_for_write(self._meta.model)
         collector = NestedObjects(using=using)
         if self.instance.pk is None:
             return
         collector.collect([self.instance])
         if collector.protected:
             objs = []
             for p in collector.protected:
                 objs.append(
                     # Translators: Model verbose name and instance representation,
                     # suitable to be an item in a list.
                     _('%(class_name)s %(instance)s') % {
                         'class_name': p._meta.verbose_name,
                         'instance': p}
                 )
             params = {'class_name': self._meta.model._meta.verbose_name,
                       'instance': self.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")
             raise ValidationError(msg, code='deleting_protected', params=params)
Exemple #34
0
    def get_deleted_objects(objs):
        """Based on `django/contrib/admin/utils.py`"""
        collector = NestedObjects(using="default")
        collector.collect(objs)

        def format_callback(obj):
            opts = obj._meta
            # Display a link to the admin page.
            try:
                return format_html(
                    '{}: <a href="{}">{}</a>',
                    capfirst(opts.verbose_name),
                    reverse(app_urlname(opts, "update"), kwargs={"pk":
                                                                 obj.pk}),
                    obj,
                )
            except NoReverseMatch:
                pass

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

        to_delete = collector.nested(format_callback)
        protected = [format_callback(obj) for obj in collector.protected]
        model_count = {
            model._meta.verbose_name_plural: len(objs)
            for model, objs in collector.model_objs.items()
        }

        return to_delete, model_count, protected
Exemple #35
0
 def get_context_data(self, **kwargs):
     context = super(Delete, self).get_context_data(**kwargs)
     context['list_reversed_url'] = reverse_lazy(TRAVEL_LIST_URL_NAME)
     collector = NestedObjects(using='default')
     collector.collect([self.get_object()])
     context['deleted_objects'] = collector.nested()
     return context
Exemple #36
0
def _merge_election(Election, old_list):
    dest_slug = old_list.pop(0)
    dest_model = None
    while not dest_model and old_list:
        try:
            dest_model = Election.objects.get(slug=dest_slug)
        except Election.DoesNotExist:
            # This election doesn't exist, so it might just exist in
            # the person versions. Because of this, it's safe to return
            # here and leave the migration to rename the slug in the versions json
            dest_slug = old_list.pop(0)
            continue
    for source_slug in old_list:
        try:
            source_model = Election.objects.get(slug=source_slug)
        except Election.DoesNotExist:
            # Same as above – if this election doesn't exist than there
            # is nothing to merge
            continue

        source_model.ballot_set.update(election=dest_model)
        source_model.officialdocument_set.update(election=dest_model)
        source_model.resultevent_set.update(election=dest_model)

        collector = NestedObjects(using=connection.cursor().db.alias)
        collector.collect([source_model])
        if len(collector.nested()) > 1:
            # A related object exist for this source election,
            # something has gone wrong.
            print(collector.nested())
            raise ValueError(
                "Can't merge election {} with related objects".format(
                    source_slug))
        source_model.delete()
    return dest_slug
Exemple #37
0
def delete_engagement(request, eid):
    engagement = get_object_or_404(Engagement, pk=eid)
    product = engagement.product
    form = DeleteEngagementForm(instance=engagement)

    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')

                if engagement.engagement_type == 'CI/CD':
                    return HttpResponseRedirect(reverse("view_engagements_cicd", args=(product.id, )))
                else:
                    return HttpResponseRedirect(reverse("view_engagements", args=(product.id, )))

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

    product_tab = Product_Tab(product.id, title="Delete Engagement", tab="engagements")
    product_tab.setEngagement(engagement)
    return render(request, 'dojo/delete_engagement.html', {
        'product_tab': product_tab,
        'engagement': engagement,
        'form': form,
        'rels': rels,
    })
Exemple #38
0
def delete_user(request, uid):
    user = get_object_or_404(Dojo_User, id=uid)
    form = DeleteUserForm(instance=user)

    from django.contrib.admin.utils 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,
                   })
Exemple #39
0
def delete_product(request, pid):
    product = get_object_or_404(Product, pk=pid)
    form = DeleteProductForm(instance=product)

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

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

    product_tab = Product_Tab(pid, title="Product", tab="settings")
    return render(
        request, 'dojo/delete_product.html', {
            'product': product,
            'form': form,
            'product_tab': product_tab,
            'rels': rels,
        })
Exemple #40
0
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.utils 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,
    })
    def delete_sql_data(self):
        for model_class, queryset in get_querysets_to_dump(self.domain_name, []):
            collector = NestedObjects(using=queryset.db)
            collector.collect(queryset)
            collector.delete()

        self.assertEqual([], list(get_objects_to_dump(self.domain_name, [])))
Exemple #42
0
def delete_engagement_presets(request, pid, eid):
    prod = get_object_or_404(Product, id=pid)
    preset = get_object_or_404(Engagement_Presets, id=eid)
    form = DeleteEngagementPresetsForm(instance=preset)

    if request.method == 'POST':
        if 'id' in request.POST:
            form = DeleteEngagementPresetsForm(request.POST, instance=preset)
            if form.is_valid():
                preset.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Engagement presets and engagement relationships removed.',
                                     extra_tags='alert-success')
                return HttpResponseRedirect(reverse('engagement_presets', args=(pid,)))

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

    product_tab = Product_Tab(pid, title="Delete Engagement Preset", tab="settings")
    return render(request, 'dojo/delete_presets.html',
                  {'product': product,
                   'form': form,
                   'product_tab': product_tab,
                   'rels': rels,
                   })
Exemple #43
0
def delete_product(request, pid):
    product = get_object_or_404(Product, pk=pid)
    form = DeleteProductForm(instance=product)

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

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

    product_tab = Product_Tab(pid, title="Product", tab="settings")
    return render(request, 'dojo/delete_product.html',
                  {'product': product,
                   'form': form,
                   'product_tab': product_tab,
                   'rels': rels,
                   })
def delete_endpoint(request, eid):
    endpoint = get_object_or_404(Endpoint, pk=eid)
    product = endpoint.product
    form = DeleteEndpointForm(instance=endpoint)

    if request.method == 'POST':
        if 'id' in request.POST and str(endpoint.id) == request.POST['id']:
            form = DeleteEndpointForm(request.POST, instance=endpoint)
            if form.is_valid():
                endpoint.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Endpoint and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(event='other',
                                    title='Deletion of %s' % endpoint,
                                    description='The endpoint "%s" was deleted by %s' % (endpoint, request.user),
                                    url=request.build_absolute_uri(reverse('endpoints')),
                                    icon="exclamation-triangle")
                return HttpResponseRedirect(reverse('view_product', args=(product.id,)))

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

    product_tab = Product_Tab(endpoint.product.id, "Delete Endpoint", tab="endpoints")

    return render(request, 'dojo/delete_endpoint.html',
                  {'endpoint': endpoint,
                   'product_tab': product_tab,
                   'form': form,
                   'rels': rels,
                   })
def get_deleted_objects(object):
    """
    List the related objects before delete an object
    """
    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([object])

    return collector.nested()
Exemple #46
0
    def get_deleted_objects(self):
        collector = NestedObjects(using=router.db_for_write(self.model))
        collector.collect([self.object])
        perms_needed = set()

        def format_callback(obj):

            p = '%s.%s' % (
                obj._meta.app_label,
                get_permission_codename('delete', obj._meta)
            )

            if not self.request.user.has_perm(p):
                perms_needed.add(obj._meta.verbose_name)

            registered = obj.__class__ in self.request.djangobmf_site.modules

            # only show bmf modules
            if not registered:
                return None

            if hasattr(obj, '_bmfmeta') and obj._bmfmeta.only_related:
                return format_html(
                    '{0}: {1}',
                    obj._meta.verbose_name,
                    obj
                )
            else:
                return format_html(
                    '{0}: <a href="{1}">{2}</a>',
                    obj._meta.verbose_name,
                    obj.bmfmodule_detail(),
                    obj
                )

        def format_protected_callback(obj):

            if obj.__class__ in self.request.djangobmf_site.modules and not obj._bmfmeta.only_related:
                return format_html(
                    '{0}: <a href="{1}">{2}</a>',
                    obj._meta.verbose_name,
                    obj.bmfmodule_detail(),
                    obj
                )
            else:
                return format_html(
                    '{0}: {1}',
                    obj._meta.verbose_name,
                    obj
                )

        to_delete = collector.nested(format_callback)

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

        return to_delete, perms_needed, protected
Exemple #47
0
 def test_relation_on_abstract(self):
     """
     #21846 -- Check that `NestedObjects.collect()` doesn't trip
     (AttributeError) on the special notation for relations on abstract
     models (related_name that contains %(app_label)s and/or %(class)s).
     """
     n = NestedObjects(using=DEFAULT_DB_ALIAS)
     Car.objects.create()
     n.collect([Vehicle.objects.first()])
Exemple #48
0
def _nested_objs(obj):
    c = NestedObjects("default")
    c.collect([obj])

    def format_callback(obj):
        return mark_safe('<a href="/keys/{}/{}/">{}</a>'.format(obj._meta.model_name, obj.pk, escape(obj)))

    result = unordered_list(c.nested(format_callback))
    return mark_safe("<ul>{}</ul>".format(result))
Exemple #49
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}
Exemple #50
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)
    def collect_objects(self, objs):
        '''
        Collect all related objects
        '''
        collector = NestedObjects(using=self.using)
        collector.collect(objs)

        if self.delete_type == 'soft_delete':
            collector = self.get_un_soft_deleted_objects(collector)

        return collector
Exemple #52
0
def get_related_objects(obj, using=DEFAULT_DB_ALIAS):
    # This code is based on https://github.com/makinacorpus/django-safedelete
    collector = NestedObjects(using=using)
    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())
Exemple #53
0
def get_merged_objects(objs, opts, user, admin_site, using):
    """
    Find all objects related to ``objs`` that should also be merged. ``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_%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)
            p = '%s.%s' % (opts.app_label,
                           opts.get_change_permission())
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            p = '%s.%s' % (opts.app_label,
                           opts.get_add_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)),
                              admin_url,
                              escape(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_merge = collector.nested(format_callback)

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

    return to_merge, perms_needed, protected
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())
Exemple #55
0
def get_delete_cascade(request, title):
	document = get_object_or_error(Document, request.user, ['change_document'], url_title=title)

	collector = NestedObjects(using=DEFAULT_DB_ALIAS)
	collector.collect([document])
	delete_cascade = collector.nested()

	# remove all subclasses of current document from the list because that does not add much helpful information
	simplified_delete_cascade = []
	for cascade_item in delete_cascade:
		if issubclass(type(document), type(cascade_item)) and not type(document) == type(cascade_item):
			continue
		simplified_delete_cascade.append(cascade_item)

	return HttpResponse(json.dumps(delete_cascade_to_json(simplified_delete_cascade)))
Exemple #56
0
    def get_deleted_objects(objs, using):
        """
        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 objects suitable for display in the
        template with the ``unordered_list`` filter.

        This is simplified from a method by the same name that the
        Django admin uses. "using" means the key in the DATABASES setting.
        """

        collector = NestedObjects(using=using)
        collector.collect(objs)
        # nested() can take a formatting callback if we want it later
        to_delete = collector.nested()
        return to_delete
Exemple #57
0
    def collect(self):
        def collect_objects(obj):
            try:
                iter(obj)
                for o in obj:
                    collect_objects(o)
            except TypeError:
                flattened.append(obj)

        collector = NestedObjects(using=self.using)
        collector.collect(self.qs)
        objs = collector.nested()
        flattened = []

        for obj in objs:
            collect_objects(obj)

        return flattened
Exemple #58
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
Exemple #59
0
    def get_info_before_delete_user(self, remove_sounds=False, remove_user=False):
        """
        This method can be called before delete_user to display to the user the
        elements that will be modified
        """

        ret = {}
        if remove_sounds:
            sounds = Sound.objects.filter(user=self.user)
            packs = Pack.objects.filter(user=self.user)
            collector = NestedObjects(using='default')
            collector.collect(sounds)
            ret['deleted'] = collector
            ret['logic_deleted'] = packs
        if remove_user:
            collector = NestedObjects(using='default')
            collector.collect([self.user])
            ret['deleted'] = collector
        ret['anonymised'] = self
        return ret
Exemple #60
0
def collect_backlinks(model_instance):
    """:param model_instance: Django Model Instance
    :return: A dict of Models that reference the current
    Useful for determining if an instance can be deleted.  Includes hyperlinks to the related models
    """
    from django.contrib.admin.utils import NestedObjects
    collector = NestedObjects(using='scenario_db')  # or specific database
    collector.collect([model_instance])  # https://docs.djangoproject.com/en/1.7/releases/1.7/#remove-and-clear-methods-of-related-managers
    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