Ejemplo n.º 1
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,
                   })
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
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,
                   })
Ejemplo n.º 4
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)
Ejemplo n.º 5
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,
    })
Ejemplo n.º 6
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,
                   })
Ejemplo n.º 7
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,
                   })
Ejemplo n.º 8
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
        )
Ejemplo n.º 9
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,
                   })
Ejemplo n.º 10
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,
                   })
Ejemplo n.º 11
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,
                   })
Ejemplo n.º 12
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, [])))
Ejemplo n.º 13
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,
                   })
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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()
Ejemplo n.º 16
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
Ejemplo n.º 17
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))
Ejemplo n.º 18
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()])
Ejemplo n.º 19
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)
Ejemplo n.º 20
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}
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
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())
Ejemplo n.º 23
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
Ejemplo n.º 24
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())
Ejemplo n.º 25
0
Archivo: views.py Proyecto: invliD/1327
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)))
Ejemplo n.º 26
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
Ejemplo n.º 27
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
Ejemplo n.º 28
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
Ejemplo n.º 29
0
def delete_finding_group(request, fgid):
    logger.debug('delete finding group: %s', fgid)
    finding_group = get_object_or_404(Finding_Group, pk=fgid)
    form = DeleteFindingGroupForm(instance=finding_group)

    if request.method == 'POST':
        if 'id' in request.POST and str(
                finding_group.id) == request.POST['id']:
            form = DeleteFindingGroupForm(request.POST, instance=finding_group)
            if form.is_valid():
                finding_group.delete()
                messages.add_message(
                    request,
                    messages.SUCCESS,
                    'Finding Group and relationships removed.',
                    extra_tags='alert-success')

                create_notification(
                    event='other',
                    title='Deletion of %s' % finding_group.name,
                    description='The finding group "%s" was deleted by %s' %
                    (finding_group.name, request.user),
                    url=request.build_absolute_uri(
                        reverse('view_test', args=(finding_group.test.id, ))),
                    icon="exclamation-triangle")
                return HttpResponseRedirect(
                    reverse('view_test', args=(finding_group.test.id, )))

    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([finding_group])
    rels = collector.nested()
    product_tab = Product_Tab(finding_group.test.engagement.product.id,
                              title="Product",
                              tab="settings")

    return render(
        request, 'dojo/delete_finding_group.html', {
            'finding_group': finding_group,
            'form': form,
            'product_tab': product_tab,
            'rels': rels,
        })
Ejemplo n.º 30
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():
                engagement.delete()
                messages.add_message(request,
                                     messages.SUCCESS,
                                     'Engagement and relationships removed.',
                                     extra_tags='alert-success')
                create_notification(
                    event='other',
                    title='Deletion of %s' % engagement.name,
                    description='The engagement "%s" was deleted by %s' %
                    (engagement.name, request.user),
                    url=request.build_absolute_uri(
                        reverse('view_engagements', args=(product.id, ))),
                    recipients=[engagement.lead],
                    icon="exclamation-triangle")

                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,
        })
Ejemplo n.º 31
0
def get_deleted_objects(objs):
    collector = NestedObjects(using='default')
    collector.collect(objs)

    #
    def format_callback(obj):
        opts = obj._meta
        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
Ejemplo n.º 32
0
    def soft_delete_cascade_policy_action(self, **kwargs):
        # Soft-delete on related objects before
        for related in related_objects(self):
            if is_safedelete_cls(related.__class__) and not getattr(related, FIELD_NAME):
                related.delete(force_policy=SOFT_DELETE, **kwargs)

        # soft-delete the object
        self._delete(force_policy=SOFT_DELETE, **kwargs)

        collector = NestedObjects(using=router.db_for_write(self))
        collector.collect([self])
        # update fields (SET, SET_DEFAULT or SET_NULL)
        for model, instances_for_fieldvalues in collector.field_updates.items():
            for (field, value), instances in instances_for_fieldvalues.items():
                query = models.sql.UpdateQuery(model)
                query.update_batch(
                    [obj.pk for obj in instances],
                    {field.name: value},
                    collector.using,
                )
Ejemplo n.º 33
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
Ejemplo n.º 34
0
def get_deleted_objects(objs, request, admin_site):
    """
    Patched django/contrib/admin/utils.py
    to skip collecting links for related nested objects
    """
    try:
        obj = objs[0]
    except IndexError:
        return [], {}, set(), []
    else:
        using = router.db_for_write(obj._meta.model)
    collector = NestedObjects(using=using)
    collector.collect(objs)
    model_count = {
        model._meta.verbose_name_plural: len(objs)
        for model, objs in collector.model_objs.items()
    }
    to_delete = [
        '{}: {}'.format(cap_words(k), v) for k, v in model_count.items()
    ]
    return to_delete, model_count, None, None
Ejemplo n.º 35
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
Ejemplo n.º 36
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

            return format_html('{0}: {1}', obj._meta.verbose_name, 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
Ejemplo n.º 37
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
Ejemplo n.º 38
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
Ejemplo n.º 39
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, [])))
Ejemplo n.º 40
0
def delete_user(request, uid):
    user = get_object_or_404(Dojo_User, id=uid)
    form = DeleteUserForm(instance=user)

    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():
                try:
                    user.delete()
                    messages.add_message(request,
                                         messages.SUCCESS,
                                         'User and relationships removed.',
                                         extra_tags='alert-success')
                except RestrictedError as err:
                    messages.add_message(
                        request,
                        messages.WARNING,
                        'User cannot be deleted: {}'.format(err),
                        extra_tags='alert-warning')
                return HttpResponseRedirect(reverse('users'))

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

    add_breadcrumb(title="Delete User", top_level=False, request=request)
    return render(request, 'dojo/delete_user.html', {
        'to_delete': user,
        'form': form,
        'rels': rels,
    })
Ejemplo n.º 41
0
def delete_rule(request, tid):
    rule = get_object_or_404(Rule, pk=tid)
    form = DeleteRuleForm(instance=rule)

    if request.method == 'POST':
        # print('id' in request.POST, file=sys.stderr)
        # print(str(rule.id) == request.POST['id'], file=sys.stderr)
        # print(str(rule.id) == request.POST['id'], file=sys.stderr)
        # if 'id' in request.POST and str(rule.id) == request.POST['id']:
        form = DeleteRuleForm(request.POST, instance=rule)
        # print(form.is_valid(), file=sys.stderr)
        # print(form.errors, file=sys.stderr)
        # print(form.non_field_errors(), file=sys.stderr)
        # print('id' in request.POST, file=sys.stderr)
        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,
        })
Ejemplo n.º 42
0
def delete_sql_data(test, models, domain):
    for model in models:
        filters = get_model_domain_filters(model, domain)
        for filter in filters:
            collector = NestedObjects(using='default')
            collector.collect(model.objects.filter(filter))
            collector.delete()
            test.assertFalse(model.objects.filter(filter).exists(), model)
Ejemplo n.º 43
0
def collect_deleted_objects(modeladmin, request, queryset):
    """Collects objects that are related to queryset items and checks
       their permissions.

       This method checks if the user has permissions to delete items that are
       anyhow related to theese in the queryset (regardless of the depth).

       ``modeladmin`` is expected to be a ModelAdmin instance corresponding
       to the class of items contained in the ``queryset``.
    """
    db_backend = router.db_for_write(queryset.first().__class__)
    # NestedObjects is undocumented API, can blow up at any time
    collector = NestedObjects(using=db_backend)
    collector.collect(queryset)

    # Check permissions and return a human-readable string representation
    perms_needed = set()

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

        if has_admin:
            model_admin = admin_site._registry[obj.__class__]
            if not request.user.is_superuser and \
                    not model_admin.has_delete_permission(request, obj):
                perms_needed.add(opts.verbose_name)

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

    # Get a nested list of dependent objects
    to_delete = collector.nested(format_callback)

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

    return to_delete, perms_needed, protected
Ejemplo n.º 44
0
def collect_deleted_objects(modeladmin, request, queryset):
    """Collects objects that are related to queryset items and checks
       their permissions.

       This method checks if the user has permissions to delete items that are
       anyhow related to theese in the queryset (regardless of the depth).

       ``modeladmin`` is expected to be a ModelAdmin instance corresponding
       to the class of items contained in the ``queryset``.
    """
    db_backend = router.db_for_write(queryset.first().__class__)
    # NestedObjects is undocumented API, can blow up at any time
    collector = NestedObjects(using=db_backend)
    collector.collect(queryset)

    # Check permissions and return a human-readable string representation
    perms_needed = set()

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

        if has_admin:
            model_admin = admin_site._registry[obj.__class__]
            if not request.user.is_superuser and \
                    not model_admin.has_delete_permission(request, obj):
                perms_needed.add(opts.verbose_name)

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

    # Get a nested list of dependent objects
    to_delete = collector.nested(format_callback)

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

    return to_delete, perms_needed, protected
Ejemplo n.º 45
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,
        })
Ejemplo n.º 46
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')
                create_notification(
                    event='other',
                    title='Deletion of JIRA: %s' %
                    jira_instance.configuration_name,
                    description='JIRA "%s" was deleted by %s' %
                    (jira_instance.configuration_name, 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,
        })
    def delete_sql_data(self):
        for model_class, builder in get_model_iterator_builders_to_dump(
                self.domain_name, []):
            for iterator in builder.querysets():
                collector = NestedObjects(using=iterator.db)
                collector.collect(iterator)
                collector.delete()

        self.assertEqual([], list(get_objects_to_dump(self.domain_name, [])))
Ejemplo n.º 48
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, )))

    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,
        })
Ejemplo n.º 49
0
def duplicate(obj, value=None, field=None, duplicate_order=None):
    """
    Duplicate all related objects of obj setting
    field to value. If one of the duplicate
    objects has an FK to another duplicate object
    update that as well. Return the duplicate copy
    of obj.
    duplicate_order is a list of models which specify how
    the duplicate objects are saved. For complex objects
    this can matter. Check to save if objects are being
    saved correctly and if not just pass in related objects
    in the order that they should be saved.
    """
    collector = NestedObjects(using=DEFAULT_DB_ALIAS)
    collector.collect([obj])
    collector.sort()
    related_models = list(collector.data.keys())
    data_snapshot = {}
    for key in list(collector.data.keys()):
        data_snapshot.update({
            key:
            dict(
                list(
                    zip([item.pk for item in collector.data[key]],
                        [item for item in collector.data[key]])))
        })
    root_obj = None

    if duplicate_order is None:
        duplicate_order = reversed(related_models)

    for model in duplicate_order:
        # Find all FKs on model that point to a related_model.
        fks = []
        for f in model._meta.fields:
            if isinstance(f, ForeignKey) and f.rel.to in related_models:
                fks.append(f)
        # Replace each `sub_obj` with a duplicate.
        if model not in collector.data:
            continue
        sub_objects = collector.data[model]
        for obj in sub_objects:
            for fk in fks:
                fk_value = getattr(obj, "%s_id" % fk.name)
                # If this FK has been duplicated then point to the duplicate.
                fk_rel_to = data_snapshot[fk.rel.to]
                if fk_value in fk_rel_to:
                    dupe_obj = fk_rel_to[fk_value]
                    setattr(obj, fk.name, dupe_obj)
            # Duplicate the object and save it.
            obj.id = None
            if field is not None:
                setattr(obj, field, value)
            obj.save()
            if root_obj is None:
                root_obj = obj
    return root_obj
Ejemplo n.º 50
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_endpoint', args=(product.id, )))

    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,
        })
Ejemplo n.º 51
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')
                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,
        })
Ejemplo n.º 52
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
             )
Ejemplo n.º 53
0
    def delete_sql_data(self):
        for model_class, builder in get_model_iterator_builders_to_dump(self.domain_name, []):
            for iterator in builder.querysets():
                with transaction.atomic(using=iterator.db), \
                        constraint_checks_deferred(iterator.db):
                    collector = NestedObjects(using=iterator.db)
                    collector.collect(iterator)
                    collector.delete()

        self.assertEqual([], list(get_objects_to_dump(self.domain_name, [])))
Ejemplo n.º 54
0
def delete_domain_sql_data_for_dump_load_test(domain_name):
    for model_class, builder in get_model_iterator_builders_to_dump(domain_name, []):
        for iterator in builder.querysets():
            with transaction.atomic(using=iterator.db), \
                 constraint_checks_deferred(iterator.db):
                collector = NestedObjects(using=iterator.db)
                collector.collect(iterator)
                collector.delete()

    assert [] == list(get_objects_to_dump(domain_name, [])), "Not all SQL objects deleted"
Ejemplo n.º 55
0
def serialize_public_draws(file_):
    backup_cutoff = dt.datetime.now(dt.timezone.utc) - dt.timedelta(days=10)
    backup_ids = set()
    collector = NestedObjects(using="default")
    for result in models.Result.objects.filter(
            schedule_date__gt=backup_cutoff):
        draw = result.draw
        if draw.id in backup_ids:
            continue
        collector.collect([draw])
        backup_ids.add(draw.id)
    for ss in models.SecretSantaResult.objects.filter(
            created_at__gt=backup_cutoff):
        collector.collect([ss])
    for payment in models.Payment.objects.filter(created_at__gt=backup_cutoff):
        collector.collect([payment])
    all_draw_objects = itertools.chain.from_iterable(collector.data.values())
    serializers.serialize("json", all_draw_objects, stream=file_)
Ejemplo n.º 56
0
    def safe_delete(self, model):
        collector = NestedObjects(using=connection.cursor().db.alias)
        collector.collect([model])
        if len(collector.nested()) > 1:
            related_objects = "\n\t".join(
                [repr(m) for m in collector.nested()[1:]])
            raise UnsafeToDelete(
                "Can't delete '{}' with related objects: \n {}".format(
                    model, related_objects))

        return model.delete()
Ejemplo n.º 57
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
Ejemplo n.º 58
0
    def xls_export(self, _models, root=None, root_qs=None):
        if (root and root_qs) or ((root or root_qs) is None):
            raise RuntimeError(
                _("Either a root object or a root queryset must be provided"))

        workbook = None
        try:
            workbookfile = self.dest or NamedTemporaryFile(dir=self.tmpdir,
                                                           delete=False)
            workbook = Workbook()
            del workbook['Sheet']

            sheets = {}

            lmodels = {}
            for k, v in _models.items():
                lname = k.lower()
                model_name = lname.rsplit('.')[1]
                lmodels[lname] = v
                sheets[model_name] = workbook.create_sheet(title=model_name)
                sheets[model_name].append(v)

            if root:
                root_qs = root._meta.model.objects.filter(pk=root.pk)

            using = router.db_for_write(root_qs.first()._meta.model)
            collector = NestedObjects(using=using)
            collector.collect(root_qs)

            def callback(obj):
                fields = lmodels.get(obj._meta.label_lower, None)
                if fields:
                    sheets[obj._meta.model_name].append(
                        [getattr(obj, x) for x in fields])

            collector.nested(callback)
            workbook.save(workbookfile)
            return workbookfile.name

        except Exception as e:
            if workbook:
                if not workbookfile.closed:
                    workbookfile.close()
                if os.path.exists(workbookfile.name):
                    os.remove(workbookfile.name)
            raise e
Ejemplo n.º 59
0
 def setUp(self):
     self.n = NestedObjects(using=DEFAULT_DB_ALIAS)
     self.objs = [Count.objects.create(num=i) for i in range(5)]
Ejemplo n.º 60
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)

    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()])