def get_queryset(self): subject = Subject.objects.get(pk=self.kwargs['subject_id']) collector = Collector(using="default") collector.collect([subject]) out = [] for model, instance in collector.instances_with_model(): if model._meta.app_label == 'data': continue if not isinstance(instance, BaseAction): continue url = reverse( 'admin:%s_%s_change' % (instance._meta.app_label, instance._meta.model_name), args=[instance.id]) item = {} clsname = instance.__class__.__name__ item['url'] = url item['name'] = model.__name__ item['type'] = getattr(instance, self.CLASS_TYPE_FIELD.get(clsname, ''), None) item['date_time'] = instance.start_time i = 0 for n in self.CLASS_FIELDS.get(clsname, ()): v = getattr(instance, n, None) if v is None: continue item['arg%d' % i] = '%s: %s' % (n, v) i += 1 out.append(item) out = sorted(out, key=itemgetter('date_time'), reverse=True) return out
def _collect_related(self, using=None, keep_parents=False): collector = Collector(using=using) collector.collect([self], keep_parents=keep_parents) fast_deletes = [] for queryset in collector.fast_deletes: if queryset.count() > 0: fast_deletes.append(queryset) return dict(instances_with_model=collector.instances_with_model(), fast_deletes=fast_deletes, data=collector.data)
def delete(self, hard=False, using=None, *args, **kwargs): # removed from the database or move to trash if self.version_in_trash or hard: # without sending signals post_delete, pre_delete self._delete(using=None, *args, **kwargs) elif hard: # with sending signals signal_allow(self, models.signals.pre_delete) signal_allow(self, models.signals.post_delete) self._delete(using=None, *args, **kwargs) signal_allow(self, models.signals.pre_delete, count=0) signal_allow(self, models.signals.post_delete, count=0) else: # with sending "virtual" signals using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val() is not None, \ "%s object can't be deleted because its %s attribute is set to None." % \ (self._meta.object_name, self._meta.pk.attname) collector = Collector(using=using) collector.collect([self]) # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: models.signals.pre_delete.send(sender=model, instance=obj, using=using) self.version_in_trash = True self.version_date = _get_current_date() self._save() # send post_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: models.signals.post_delete.send(sender=model, instance=obj, using=using)
def delete(self, hard=False, using=None, *args, **kwargs): # removed from the database or move to trash if self.version_in_trash or hard: # without sending signals post_delete, pre_delete self._delete(using=None, *args, **kwargs) elif hard: # with sending signals signal_allow(self, models.signals.pre_delete) signal_allow(self, models.signals.post_delete) self._delete(using=None, *args, **kwargs) signal_allow(self, models.signals.pre_delete, count=0) signal_allow(self, models.signals.post_delete, count=0) else: # with sending "virtual" signals using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val() is not None, \ "%s object can't be deleted because its %s attribute is set to None." % \ (self._meta.object_name, self._meta.pk.attname) collector = Collector(using=using) collector.collect([self]) # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: models.signals.pre_delete.send( sender=model, instance=obj, using=using ) self.version_in_trash = True self.version_date = _get_current_date() self._save() # send post_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: models.signals.post_delete.send( sender=model, instance=obj, using=using )
def handle_eighth_sponsor_deletion(in_obj, eighth_sponsor): teststaff, _ = get_user_model().objects.get_or_create(id=7011) c = Collector(using="default") c.collect([in_obj]) objects = c.instances_with_model() for obj in objects: if not isinstance(obj[1], eighth_sponsor): obj[1].user = teststaff obj[1].save() else: original = obj[1] original.delete()
def get_context_data(self, **kwargs): context = super(DynamicDeleteView, self).get_context_data(**kwargs) collector = Collector(using='default') # or specific database collector.collect([self.object]) to_delete = collector.instances_with_model() context['to_delete_list'] = [] for x, y in to_delete: context['to_delete_list'].append((x.__name__, y,)) return context
def handle_eighth_sponsor_deletion(in_obj, eighth_sponsor): teststaff = User.get_user(id=7011) c = Collector(using="default") c.collect([in_obj]) objects = c.instances_with_model() for obj in objects: if not isinstance(obj[1], eighth_sponsor): obj[1].user = teststaff obj[1].save() else: original = obj[1] original.delete()
def get_related_models(queryset): related_objects = defaultdict(dict) for main_object in queryset: collector = Collector(using='default') # or specific database collector.collect([main_object]) main_key = main_object.id for model, instance in collector.instances_with_model(): try: related_objects[main_key][model.__name__].append(instance) except KeyError: related_objects[main_key][model.__name__] = [instance] return related_objects
def get_context_data(self, **kwargs): context = super(DynamicDeleteView, self).get_context_data(**kwargs) collector = Collector(using='default') # or specific database collector.collect([self.object]) to_delete = collector.instances_with_model() context['to_delete_list'] = [] for x, y in to_delete: context['to_delete_list'].append(( x.__name__, y, )) return context
def spam_can_comment(request, comment_id): try: comment = Comment.objects.org_filter(request.user).get( pk=comment_id, comment_doc__isnull=True) except Comment.DoesNotExist: raise Http404 # Only moderators can delete; and exclude bloggers, superusers, and # moderators from being deleted. can_del_user = request.user.has_perm("auth.delete_user") \ and not comment.user.is_superuser \ and not comment.user.groups.filter(name='moderators').exists() \ and not comment.user.profile.managed if request.method == 'POST': redirect_url = comment.document.get_absolute_url() if can_del_user and request.POST.get("delete_user"): comment.user.delete() messages.success(request, "User and all user's content deleted.") else: comment.removed = True comment.save() messages.success(request, "Comment removed.") return redirect(redirect_url) also_deleted = None if can_del_user: # Get a list of things that will be deleted if the user is. collector = Collector(using='default') collector.collect([comment.user]) also_deleted = [] for model, instance in collector.instances_with_model(): if instance != comment.user: also_deleted.append((instance._meta.object_name, instance)) return render( request, "comments/spam_can_comment.html", { 'comment': comment, 'can_del_user': can_del_user, 'also_deleted': also_deleted, })
def spam_can_comment(request, comment_id): try: comment = Comment.objects.org_filter(request.user).get( pk=comment_id, comment_doc__isnull=True) except Comment.DoesNotExist: raise Http404 # Only moderators can delete; and exclude bloggers, superusers, and # moderators from being deleted. can_del_user = request.user.has_perm("auth.delete_user") \ and not comment.user.is_superuser \ and not comment.user.groups.filter(name='moderators').exists() \ and not comment.user.profile.managed if request.method == 'POST': redirect_url = comment.document.get_absolute_url() if can_del_user and request.POST.get("delete_user"): comment.user.delete() messages.success(request, "User and all user's content deleted.") else: comment.removed = True comment.save() messages.success(request, "Comment removed.") return redirect(redirect_url) also_deleted = None if can_del_user: # Get a list of things that will be deleted if the user is. collector = Collector(using='default') collector.collect([comment.user]) also_deleted = [] for model, instance in collector.instances_with_model(): if instance != comment.user: also_deleted.append((instance._meta.object_name, instance)) return render(request, "comments/spam_can_comment.html", { 'comment': comment, 'can_del_user': can_del_user, 'also_deleted': also_deleted, })
def delete(self, using=None, keep_parents=False, **kwargs): """ Mark this instance as deleted and call `delete()` on all related objects. Don’t call `super`! """ logger.info('DELETE %s' % self) self.deleted = True self.save(**kwargs) # the following is copied from django.db.models.base.Model using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val() is not None, ( "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)) # Find all the related objects that need to be deleted. collector = Collector(using=using) collector.collect([self], keep_parents=keep_parents) #return collector.delete() # remove self from deletion collection myself_and_friends = collector.data[type(self)].remove(self) if myself_and_friends: collector.data[type(self)] = myself_and_friends else: del collector.data[type(self)] # Problem: collector.delete() doesn’t call object’s delete method, but deletes! # The following is copied from collector.delete() (db.models.deletion) # sort instance collections for model, instances in collector.data.items(): collector.data[model] = sorted(instances, key=attrgetter("pk")) # if possible, bring the models in an order suitable for databases that # don't support transactions or cannot defer constraint checks until the # end of a transaction. collector.sort() # number of objects deleted for each model label deleted_counter = Counter() with transaction.atomic(using=collector.using, savepoint=False): # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.pre_delete.send(sender=model, instance=obj, using=collector.using) ## fast deletes #for qs in collector.fast_deletes: # count = qs._raw_delete(using=collector.using) # deleted_counter[qs.model._meta.label] += count # update fields for model, instances_for_fieldvalues in six.iteritems( collector.field_updates): query = sql.UpdateQuery(model) for (field, value ), instances in six.iteritems(instances_for_fieldvalues): query.update_batch([obj.pk for obj in instances], {field.name: value}, collector.using) # reverse instance collections for instances in six.itervalues(collector.data): instances.reverse() # delete instances for model, instances in six.iteritems(collector.data): if not issubclass(model, DorsaleBaseModel): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] count = query.delete_batch(pk_list, collector.using) deleted_counter[model._meta.label] += count else: for inst in instances: inst.delete() # expensive operation! if not model._meta.auto_created: for obj in instances: signals.post_delete.send(sender=model, instance=obj, using=collector.using) # update collected instances for model, instances_for_fieldvalues in six.iteritems( collector.field_updates): for (field, value), instances in six.iteritems(instances_for_fieldvalues): for obj in instances: setattr(obj, field.attname, value) for model, instances in six.iteritems(collector.data): for instance in instances: setattr(instance, model._meta.pk.attname, None) return sum(deleted_counter.values()), dict(deleted_counter)
def related_objects(target): collector = Collector(None) collector.add([target]) yield from collector.instances_with_model()
def delete(self, using=None, *args, **kwargs): """ Mark this instance as deleted and call `delete()` on all related objects. Don’t call `super`! """ logger.info('DELETE %s' % self) self.deleted = True self.save(*args, **kwargs) # the following is copied from django.db.models.base.Model using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val( ) is not None, "%s object can't be deleted because its %s attribute is set to None." % ( self._meta.object_name, self._meta.pk.attname) # Find all the related objects than need to be deleted. collector = Collector(using=using) collector.collect([self]) # remove self from deletion collection myself_and_friends = collector.data[type(self)].remove(self) if myself_and_friends: collector.data[type(self)] = myself_and_friends else: del collector.data[type(self)] # Problem: collector.delete() doesn’t call object’s delete method, but deletes! # The following is copied from collector.delete() # sort instance collections for model, instances in collector.data.items(): collector.data[model] = sorted(instances, key=attrgetter("pk")) # if possible, bring the models in an order suitable for databases that # don't support transactions or cannot defer contraint checks until the # end of a transaction. collector.sort() # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.pre_delete.send(sender=model, instance=obj, using=collector.using) # update fields for model, instances_for_fieldvalues in collector.field_updates.iteritems( ): query = sql.UpdateQuery(model) for (field, value), instances in instances_for_fieldvalues.iteritems(): query.update_batch([obj.pk for obj in instances], {field.name: value}, collector.using) # reverse instance collections for instances in collector.data.itervalues(): instances.reverse() # delete batches for model, batches in collector.batches.iteritems(): if not issubclass(model, CerebraleBaseModel): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) for field, instances in batches.iteritems(): query.delete_batch([obj.pk for obj in instances], collector.using, field) else: # don’t know what to do pass # delete instances for model, instances in collector.data.iteritems(): if not issubclass(model, CerebraleBaseModel): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] query.delete_batch(pk_list, collector.using) else: for inst in instances: inst.delete() # expensive operation! # send post_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.post_delete.send(sender=model, instance=obj, using=collector.using) # update collected instances for model, instances_for_fieldvalues in collector.field_updates.iteritems( ): for (field, value), instances in instances_for_fieldvalues.iteritems(): for obj in instances: setattr(obj, field.attname, value) for model, instances in collector.data.iteritems(): for instance in instances: setattr(instance, model._meta.pk.attname, None)
def delete(self, using=None, *args, **kwargs): """ Mark this instance as deleted and call `delete()` on all related objects. Don’t call `super`! """ logger.info('DELETE %s' % self) self.deleted = True self.save(*args, **kwargs) # the following is copied from django.db.models.base.Model using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname) # Find all the related objects than need to be deleted. collector = Collector(using=using) collector.collect([self]) # remove self from deletion collection myself_and_friends = collector.data[type(self)].remove(self) if myself_and_friends: collector.data[type(self)] = myself_and_friends else: del collector.data[type(self)] # Problem: collector.delete() doesn’t call object’s delete method, but deletes! # The following is copied from collector.delete() # sort instance collections for model, instances in collector.data.items(): collector.data[model] = sorted(instances, key=attrgetter("pk")) # if possible, bring the models in an order suitable for databases that # don't support transactions or cannot defer contraint checks until the # end of a transaction. collector.sort() # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.pre_delete.send( sender=model, instance=obj, using=collector.using ) # update fields for model, instances_for_fieldvalues in collector.field_updates.iteritems(): query = sql.UpdateQuery(model) for (field, value), instances in instances_for_fieldvalues.iteritems(): query.update_batch([obj.pk for obj in instances], {field.name: value}, collector.using) # reverse instance collections for instances in collector.data.itervalues(): instances.reverse() # delete batches for model, batches in collector.batches.iteritems(): if not issubclass(model, CerebraleBaseModel): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) for field, instances in batches.iteritems(): query.delete_batch([obj.pk for obj in instances], collector.using, field) else: # don’t know what to do pass # delete instances for model, instances in collector.data.iteritems(): if not issubclass(model, CerebraleBaseModel): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] query.delete_batch(pk_list, collector.using) else: for inst in instances: inst.delete() # expensive operation! # send post_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.post_delete.send( sender=model, instance=obj, using=collector.using ) # update collected instances for model, instances_for_fieldvalues in collector.field_updates.iteritems(): for (field, value), instances in instances_for_fieldvalues.iteritems(): for obj in instances: setattr(obj, field.attname, value) for model, instances in collector.data.iteritems(): for instance in instances: setattr(instance, model._meta.pk.attname, None)
def delete(self, using=None, keep_parents=False, **kwargs): """ Mark this instance as deleted and call `delete()` on all related objects. Don’t call `super`! """ logger.info('DELETE %s' % self) self.deleted = True self.save(**kwargs) # the following is copied from django.db.models.base.Model using = using or router.db_for_write(self.__class__, instance=self) assert self._get_pk_val() is not None, ( "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname) ) # Find all the related objects that need to be deleted. collector = Collector(using=using) collector.collect([self], keep_parents=keep_parents) #return collector.delete() # remove self from deletion collection myself_and_friends = collector.data[type(self)].remove(self) if myself_and_friends: collector.data[type(self)] = myself_and_friends else: del collector.data[type(self)] # Problem: collector.delete() doesn’t call object’s delete method, but deletes! # The following is copied from collector.delete() (db.models.deletion) # sort instance collections for model, instances in collector.data.items(): collector.data[model] = sorted(instances, key=attrgetter("pk")) # if possible, bring the models in an order suitable for databases that # don't support transactions or cannot defer constraint checks until the # end of a transaction. collector.sort() # number of objects deleted for each model label deleted_counter = Counter() with transaction.atomic(using=collector.using, savepoint=False): # send pre_delete signals for model, obj in collector.instances_with_model(): if not model._meta.auto_created: signals.pre_delete.send( sender=model, instance=obj, using=collector.using ) ## fast deletes #for qs in collector.fast_deletes: # count = qs._raw_delete(using=collector.using) # deleted_counter[qs.model._meta.label] += count # update fields for model, instances_for_fieldvalues in six.iteritems(collector.field_updates): query = sql.UpdateQuery(model) for (field, value), instances in six.iteritems(instances_for_fieldvalues): query.update_batch([obj.pk for obj in instances], {field.name: value}, collector.using) # reverse instance collections for instances in six.itervalues(collector.data): instances.reverse() # delete instances for model, instances in six.iteritems(collector.data): if not issubclass(model, FakeDeleteMixin): # handle non-cerebrale models as usual query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] count = query.delete_batch(pk_list, collector.using) deleted_counter[model._meta.label] += count else: for inst in instances: inst.delete() # expensive operation! if not model._meta.auto_created: for obj in instances: signals.post_delete.send( sender=model, instance=obj, using=collector.using ) # update collected instances for model, instances_for_fieldvalues in six.iteritems(collector.field_updates): for (field, value), instances in six.iteritems(instances_for_fieldvalues): for obj in instances: setattr(obj, field.attname, value) for model, instances in six.iteritems(collector.data): for instance in instances: setattr(instance, model._meta.pk.attname, None) return sum(deleted_counter.values()), dict(deleted_counter)