예제 #1
0
    def delete(self, force=False):
        """
        Deletes the records in the current QuerySet.
        """
        assert self.query.can_filter(), \
            "Cannot use 'limit' or 'offset' with delete."

        del_query = self._clone()

        # The delete is actually 2 queries - one to find related objects,
        # and one to delete. Make sure that the discovery of related
        # objects is performed on the same database as the deletion.
        del_query._for_write = True

        # Disable non-supported fields.
        del_query.query.select_for_update = False
        del_query.query.select_related = False
        del_query.query.clear_ordering(force_empty=True)

        collector = Collector(using=del_query.db)
        collector.collect(del_query)
        collector.delete(force=force)

        # Clear the result cache, in case this QuerySet gets reused.
        self._result_cache = None
예제 #2
0
    def delete(self, using=None):
        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 objects than need to be deleted.
        collector = Collector(using=using)
        collector.collect([self])

        #hack to prevent ORM delet object via sql
        #it does not use QuerySet - directly sql module :(
        to_delete = {}
        for k in collector.data.keys()[:]:
            if issubclass(k, MongoModel):
                to_delete.update({k: collector.data.pop(k)})

        for key, object_set in to_delete.items():
            for obj in object_set:
                cls = obj.__class__
                if not cls._meta.auto_created:
                    models.signals.pre_delete.send(sender=cls, instance=obj)

                cls._default_manager.filter(pk=obj.pk).delete()

                if not cls._meta.auto_created:
                    models.signals.post_delete.send(sender=cls, instance=obj)

        # Delete other objects.
        collector.delete()
예제 #3
0
    def delete_related(self, affected=None, using=None):
        """
        Стандартное каскадное удаление объектов в django,
        дополненное проверкой на удаляемые классы моделей affected.
        По умолчанию affected содержит пустой список
        - это ограничивает удаляемые модели только текущим классом.
        К перечисленным в affected классам текущий добавляется автоматически.
        Если удаление не удалось выполнить, возвращает False, иначе True.
        Пример:
            Model1.objects.get(id=1).delete_related(affected=[Model2, Model3])
        """
        # Кописаст из django.db.models.Model delete()
        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])
        # cut

        affected = affected or []
        assert isinstance(affected,
                          list), ('Affected models must be the list type')
        affected.append(self.__class__)

        for model in collector.data.keys():
            if model not in affected:
                return False

        collector.delete()
        return True
예제 #4
0
 def revert(self, delete=False):
     # Group the models by the database of the serialized model.
     versions_by_db = defaultdict(list)
     for version in self.version_set.iterator():
         versions_by_db[version.db].append(version)
     # For each db, perform a separate atomic revert.
     for version_db, versions in versions_by_db.items():
         with transaction.atomic(using=version_db):
             # Optionally delete objects no longer in the current revision.
             if delete:
                 # Get a set of all objects in this revision.
                 old_revision = set()
                 for version in versions:
                     model = version._model
                     try:
                         # Load the model instance from the same DB as it was saved under.
                         old_revision.add(model._default_manager.using(version.db).get(pk=version.object_id))
                     except model.DoesNotExist:
                         pass
                 # Calculate the set of all objects that are in the revision now.
                 current_revision = chain.from_iterable(
                     _follow_relations_recursive(obj)
                     for obj in old_revision
                 )
                 # Delete objects that are no longer in the current revision.
                 collector = Collector(using=version_db)
                 new_objs = [item for item in current_revision
                             if item not in old_revision]
                 for model, group in groupby(new_objs, type):
                     collector.collect(list(group))
                 collector.delete()
             # Attempt to revert all revisions.
             _safe_revert(versions)
예제 #5
0
 def revert(self, delete=False):
     # Group the models by the database of the serialized model.
     versions_by_db = defaultdict(list)
     for version in self.version_set.iterator():
         versions_by_db[version.db].append(version)
     # For each db, perform a separate atomic revert.
     for version_db, versions in versions_by_db.items():
         with transaction.atomic(using=version_db):
             # Optionally delete objects no longer in the current revision.
             if delete:
                 # Get a set of all objects in this revision.
                 old_revision = set()
                 for version in versions:
                     model = version._model
                     try:
                         # Load the model instance from the same DB as it was saved under.
                         old_revision.add(model._default_manager.using(version.db).get(pk=version.object_id))
                     except model.DoesNotExist:
                         pass
                 # Calculate the set of all objects that are in the revision now.
                 current_revision = chain.from_iterable(
                     _follow_relations_recursive(obj)
                     for obj in old_revision
                 )
                 # Delete objects that are no longer in the current revision.
                 collector = Collector(using=version_db)
                 new_objs = [item for item in current_revision
                             if item not in old_revision]
                 for model, group in groupby(new_objs, type):
                     collector.collect(list(group))
                 collector.delete()
             # Attempt to revert all revisions.
             _safe_revert(versions)
예제 #6
0
    def delete(self, using=None):
        """Surcharge de la methode save pour supprimer le fichier source avant l objet
        """
        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,
        )

        if self.source_file:
            tab_path = self.source_file.name.split("/")  # decoupage du chemin vers le fichier source
            rep_path = os.path.join(
                os.path.join(settings.VIDEO_ROOT, tab_path[1]).replace("\\", "/")
            )  # recomposition du chemin du repertoire du fichier source

            self.source_file.delete()  # suppression du fichier source
            if len(os.listdir(rep_path)) == 0:  # si le repertoire du fichier source est vide
                try:
                    os.rmdir(rep_path)  # suppression du repertoire
                except:
                    pass  # Si un probleme survient on ne fait rien

        collector = Collector(using=using)
        collector.collect([self])
        collector.delete()
예제 #7
0
    def delete(self, force=False):
        """
        Deletes the records in the current QuerySet.
        """
        assert self.query.can_filter(), \
            "Cannot use 'limit' or 'offset' with delete."

        del_query = self._clone()

        # The delete is actually 2 queries - one to find related objects,
        # and one to delete. Make sure that the discovery of related
        # objects is performed on the same database as the deletion.
        del_query._for_write = True

        # Disable non-supported fields.
        del_query.query.select_for_update = False
        del_query.query.select_related = False
        del_query.query.clear_ordering(force_empty=True)

        collector = Collector(using=del_query.db)
        collector.collect(del_query)
        collector.delete(force=force)

        # Clear the result cache, in case this QuerySet gets reused.
        self._result_cache = None
예제 #8
0
 def delete(self, using=None):
     # FIXME: if the Translation is the one used as default/fallback,
     # then deleting it will mean the corresponding field on the related
     # model will stay empty even if there are translations in other
     # languages!
     cls = self.__class__
     using = using or router.db_for_write(cls, instance=self)
     # Look for all translations for the same string (id=self.id) except the
     # current one (autoid=self.autoid).
     qs = cls.objects.filter(id=self.id).exclude(autoid=self.autoid)
     if qs.using(using).exists():
         # If other Translations for the same id exist, we just need to
         # delete this one and *only* this one, without letting Django
         # collect dependencies (it'd remove the others, which we want to
         # keep).
         assert self._get_pk_val() is not None
         collector = Collector(using=using)
         collector.collect([self], collect_related=False)
         # In addition, because we have FK pointing to a non-unique column,
         # we need to force MySQL to ignore constraints because it's dumb
         # and would otherwise complain even if there are remaining rows
         # that matches the FK.
         with connections[using].constraint_checks_disabled():
             collector.delete()
     else:
         # If no other Translations with that id exist, then we should let
         # django behave normally. It should find the related model and set
         # the FKs to NULL.
         return super(Translation, self).delete(using=using)
예제 #9
0
파일: base.py 프로젝트: whardier/django
    def delete(self, using=None):
        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])
        collector.delete()
예제 #10
0
파일: models.py 프로젝트: gadio/moma-django
    def delete(self, using=None):
        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 objects than need to be deleted.
        collector = Collector(using=using)
        collector.collect([self])

        # hack to prevent ORM delet object via sql
        # it does not use QuerySet - directly sql module :(
        to_delete = {}
        for k in collector.data.keys()[:]:
            if issubclass(k, MongoModel):
                to_delete.update({k: collector.data.pop(k)})

        for key, object_set in to_delete.items():
            for obj in object_set:
                cls = obj.__class__
                if not cls._meta.auto_created:
                    models.signals.pre_delete.send(sender=cls, instance=obj)

                cls._default_manager.filter(pk=obj.pk).delete()

                if not cls._meta.auto_created:
                    models.signals.post_delete.send(sender=cls, instance=obj)

        # Delete other objects.
        collector.delete()
예제 #11
0
파일: base.py 프로젝트: dynamicguy/django
    def delete(self, using=None):
        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])
        collector.delete()
예제 #12
0
    def delete(self):
        """
        Deletes the records in the current QuerySet.
        """
        assert self.query.can_filter(), \
                "Cannot use 'limit' or 'offset' with delete."

        # NB: this line is patched to work with SkinnyQuerySet
        # see https://gist.github.com/550438#file-gistfile2-txt
        del_query = self._clone(klass=QuerySet)

        # The delete is actually 2 queries - one to find related objects,
        # and one to delete. Make sure that the discovery of related
        # objects is performed on the same database as the deletion.
        del_query._for_write = True

        # Disable non-supported fields.
        del_query.query.select_for_update = False
        del_query.query.select_related = False
        del_query.query.clear_ordering(force_empty=True)

        collector = Collector(using=del_query.db)
        collector.collect(del_query)
        collector.delete()

        # Clear the result cache, in case this QuerySet gets reused.
        self._result_cache = None
예제 #13
0
    def handle(self, *args, **options):
        verbosity = int(options.get("verbosity", "1"))
        levels = (logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG)

        if "verbosity" in options:
            logging.basicConfig(format='%(message)s', level=levels[verbosity])

        if options['days'] < 7 and not options['force']:
            logger.error(
                'Delete less than one week not allowed, try using --force')
            return

        if options['days'] < 1:
            logger.error('Delete less than one day not allowed at all')
            return

        start_date = timezone.now() - timedelta(days=options['days'])
        collector = Collector(using=DEFAULT_DB_ALIAS)

        logger.info("Purge old chat records since {}".format(start_date))

        for model in [ChatHistory]:
            qs = model.objects.filter(created__lt=start_date)
            logger.info("Delete {} records in {}".format(
                qs.count(), model._meta.db_table))
            collector.collect(qs)
            collector.delete()

        logger.info("Done purging old records.")
예제 #14
0
파일: base.py 프로젝트: lisael/pg-django
    def delete(self, using=None):
        if (self.__class__._meta.materialized_view or
                    (self.__class__._meta.intermediate and not
                     self.__class__._meta.concrete)):
            raise NonPersistantModel('Materialized views and intermediate views can\'t be'\
                            'saved or deleted')
        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])
        collector.delete()
예제 #15
0
 def delete(self, **kwargs):
     """
         Deletes fields from base model
     """
     assert self._get_pk_val(
     ) is not None, "Object %s cannot be deleted because %s is null." % (
         self._meta.object_name, self._meta.pk.attname)
     seen_objs = Collector(
         router.db_for_write(self.__class__, instance=self))
     seen_objs.collect([self])
     self.can_delete()
     seen_objs.delete()
    def delete(self, *args, **kwargs):
        """
        Replace  super(BaseModel, self).delete()
        Cause: When delete relationship in cascade  default no have attribute User to Log.
        """

        using = 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])

        collector.delete()
예제 #17
0
    def delete(self, *args, **kwargs):
        '''
        Replace  super(BaseModel, self).delete()
        Cause: When delete relationship in cascade  default no have attribute User to Log.
        '''

        using = 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])

        collector.delete()
예제 #18
0
    def handle(self, *args, **options):
        verbosity = int(options.get("verbosity", "1"))
        levels = (logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG)

        if "verbosity" in options:
            logging.basicConfig(format='%(message)s', level=levels[verbosity])

        if options['days'] < 7 and not options['force']:
            logger.error('Delete less than one week not allowed, try using --force')
            return

        if options['days'] < 1:
            logger.error('Delete less than one day not allowed at all')
            return

        start_date = timezone.now() - timedelta(days=options['days'])
        collector = Collector(using=DEFAULT_DB_ALIAS)

        logger.info("Purge old records since {}".format(start_date))

        for model in (NotifySend, TaskReport):
            qs = model.objects.filter(created__lt=start_date)
            logger.info("Delete {} records in {}".format(qs.count(), model._meta.db_table))
            collector.collect(qs)
            collector.delete()

        logger.info("Done purging old records.")

        if not options['vacuum']:
            return

        sql = "VACUUM"

        if options['full']:
            sql += " FULL"

        force_proxy = connection.cursor()
        realconn = connection.connection
        old_isolation_level = realconn.isolation_level
        realconn.set_isolation_level(0)
        cursor = realconn.cursor()

        for model in (NotifySend, TaskReport):
            sql_command = "{} {}".format(sql, model._meta.db_table)
            logger.info("Run {}".format(sql_command))
            cursor.execute(sql_command)

        realconn.set_isolation_level(old_isolation_level)
        del force_proxy
예제 #19
0
    def hard_delete(self):
        """Delete the records in the current QuerySet."""
        self._not_support_combined_queries('delete')
        assert not self.query.is_sliced, \
            "Cannot use 'limit' or 'offset' with delete."

        if self._fields is not None:
            raise TypeError(
                "Cannot call delete() after .values() or .values_list()")

        del_query = self._chain()

        # The delete is actually 2 queries - one to find related objects,
        # and one to delete. Make sure that the discovery of related
        # objects is performed on the same database as the deletion.
        del_query._for_write = True

        # Disable non-supported fields.
        del_query.query.select_for_update = False
        del_query.query.select_related = False
        del_query.query.clear_ordering(force_empty=True)

        collector = Collector(using=del_query.db)
        collector.collect(del_query)
        deleted, _rows_count = collector.delete()

        # Clear the result cache, in case this QuerySet gets reused.
        self._result_cache = None
        return deleted, _rows_count
예제 #20
0
    def delete_without_cascade(self, using=None, keep_parents=False):
        """
        Modified version of django's default delete() method.

        This method is added to enable safe deletion of the child models without
        removing objects related to it through the parent. As of Feb 2017,
        no models are directly related to the OAuth2DataRequestProject or
        OnSiteDataRequestProject child models.
        """
        allowed_models = [
            "private_sharing.onsitedatarequestproject",
            "private_sharing.oauth2datarequestproject",
        ]
        if self._meta.label_lower not in allowed_models:
            raise Exception("'delete_without_cascade' only for child models!")
        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],
                          keep_parents=keep_parents,
                          collect_related=False)
        return collector.delete()
예제 #21
0
def soft_delete(self, *args, **kwargs):
    if len(self.data) > 0:
        # normal deletes
        for model, instances in self.data.iteritems():
            if issubclass(model, SoftDeletableModel):
                for instance in instances:
                    instance.is_active = False
                    instance.save()
            else:
                collector = Collector(using=None) # use the default db
                collector.collect(instances)
                collector.delete()
    else:
        # fast deletes
        for qs in self.fast_deletes:
            qs.update(is_active=False)
예제 #22
0
def soft_delete(self, *args, **kwargs):
    if len(self.data) > 0:
        # normal deletes
        for model, instances in self.data.iteritems():
            if issubclass(model, SoftDeletableModel):
                for instance in instances:
                    instance.is_active = False
                    instance.save()
            else:
                collector = Collector(using=None)  # use the default db
                collector.collect(instances)
                collector.delete()
    else:
        # fast deletes
        for qs in self.fast_deletes:
            qs.update(is_active=False)
예제 #23
0
def change_spanish_home_pages_to_home_pages(apps, schema_editor):
    SpanishHomePage = apps.get_model('v1', 'SpanishHomePage')
    spanish_home_pages = SpanishHomePage.objects.all()

    # If there are no SpanishHomePages, nothing to do.
    if not spanish_home_pages.exists():
        return

    ContentType = apps.get_model('contenttypes', 'ContentType')
    Page = apps.get_model('wagtailcore', 'Page')
    PageRevision = apps.get_model('wagtailcore', 'PageRevision')

    # When running migrations against an empty database, there won't already
    # be a ContentType for the HomePage model type. But we need one in order to
    # convert SpanishHomePages to that type. So use get_or_create here to
    # either use the existing ContentType or create a new one.
    homepage_content_type, _ = ContentType.objects.get_or_create(
        app_label='v1', model='homepage')

    # This is by no means a general solution to the problem of changing a
    # Wagtail Page's type, but seems to work for this specific situation, where
    # we meet these requirements:
    #
    # - Changing a child page into its immediate parent's page type
    # - There are no foreign keys from the child page type to other models
    # - There are no foreign keys from other models to the child page type
    collector = Collector(using=schema_editor.connection.alias)

    for page in spanish_home_pages:
        # This deletes the page's row in the v1_spanishhomepage table without
        # touching the parent v1_homepage, v1_cfgovpage, or wagtailcore_page
        # tables.
        collector.collect([page], keep_parents=True, collect_related=False)
        collector.delete()

        # This updates the wagtailcore_page table to set the page's new type.
        page.content_type = homepage_content_type
        Page.save(page, update_fields=['content_type'])

        # Finally fixup existing page revisions so they also have the right
        # content type. This doesn't affect anything, but is good for
        # consistency.
        for revision in PageRevision.objects.filter(page_id=page.pk):
            content = json.loads(revision.content_json)
            content['content_type'] = homepage_content_type.pk
            revision.content_json = json.dumps(content)
            revision.save(update_fields=['content_json'])
예제 #24
0
    def delete_complete(self, using=None, keep_parents=False):
        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], keep_parents=keep_parents)
        return collector.delete()
예제 #25
0
    def delete(self, using=None):
        """Surcharge de la methode save pour supprimer le fichier source avant l objet
        """
        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,
        )

        if self.outputdir:
            try:
                shutil.rmtree(
                    os.path.join(settings.VIDEO_ROOT, self.outputdir).replace("\\", "/")
                )  # suppression du repertoire
            except:
                pass  # Si un probleme survient on ne fait rien

        collector = Collector(using=using)
        collector.collect([self])
        collector.delete()
예제 #26
0
    def delete(self, using=None, keep_parents=False):
        using = using or router.db_for_write(self.__class__, instance=self)
        collector = Collector(using=using)
        collector.collect([self], keep_parents=keep_parents)

        if (self.registration_reminder is not None
                and not self.registration_reminder.sent):
            collector.add([self.registration_reminder])
        if self.start_reminder is not None and not self.start_reminder.sent:
            collector.add([self.start_reminder])
        if self.is_pizza_event():
            collector.add([self.pizzaevent])

        return collector.delete()
예제 #27
0
    def delete_related(self, affected=None, using=None):
        """
        Стандартное каскадное удаление объектов в django,
        дополненное проверкой на удаляемые классы моделей affected.
        По умолчанию affected содержит пустой список
        - это ограничивает удаляемые модели только текущим классом.
        К перечисленным в affected классам текущий добавляется автоматически.
        Если удаление не удалось выполнить, возвращает False, иначе True.
        Пример:
            Model1.objects.get(id=1).delete_related(affected=[Model2, Model3])
        """
        # Кописаст из django.db.models.Model delete()
        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])
        # cut

        affected = affected or []
        assert isinstance(affected, list), (
            'Affected models must be the list type')
        affected.append(self.__class__)

        for model in collector.data.keys():
            if model not in affected:
                return False

        collector.delete()
        return True
예제 #28
0
 def delete(self, using=None, keep_parents=False, hard_delete=False, *args, **kwargs):
     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], keep_parents=keep_parents)
     with transaction.atomic():
         if hard_delete:
             # set hard deletion for all related models
             for model, instances in six.iteritems(collector.data):
                 if issubclass(model, SyncableModel) or issubclass(model, MorangoMPTTModel):
                     for obj in instances:
                         obj._update_hard_deleted_models()
         return collector.delete()
    def delete(self, using=None, keep_parents=False):
        using = using or router.db_for_write(self.__class__, instance=self)
        assert self.pk 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)
        # Change S
        #   MEMO: Collector doesn't support method to change its base query.
        #           Therefore, I changed param '[self]' to CPkQuerySet object.
        #
        #collector.collect([self], keep_parents=keep_parents)
        model = self._meta.model
        qs = model.objects.filter(pk=self.pk)
        collector.collect(qs, keep_parents=keep_parents)
        # Change E
        return collector.delete()
예제 #30
0
    def delete(self, using=None, keep_parents=False, use_protection=False):
        """
        delete the object

        Parameters:
        using: str, optional
        keep_parents: bool, optional(default=False)

        use_protection: bool, optional(default=False)
            if True, raise a ProtectedError
            when trying to delete related objects if on_delete=PROTECT_CASCADE
            if False, delete objects cascaded
        """
        using = using or router.db_for_write(self.__class__, instance=self)
        assert self.pk 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.use_protection = use_protection
        collector.collect([self], keep_parents=keep_parents)
        return collector.delete()
예제 #31
0
    def delete_without_cascade(self, using=None, keep_parents=False):
        """
        Modified version of django's default delete() method.

        This method is added to enable safe deletion of the child models without
        removing objects related to it through the parent. As of Feb 2017,
        no models are directly related to the OAuth2DataRequestProject or
        OnSiteDataRequestProject child models.
        """
        allowed_models = [
            "private_sharing.onsitedatarequestproject",
            "private_sharing.oauth2datarequestproject",
        ]
        if self._meta.label_lower not in allowed_models:
            raise Exception("'delete_without_cascade' only for child models!")
        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], keep_parents=keep_parents, collect_related=False)
        return collector.delete()
예제 #32
0
    def save(self, *args, **kwargs):
        delete_collector = Collector(
            using=router.db_for_write(self.__class__, instance=self))

        if not self.pk:
            super().save(*args, **kwargs)

        if self.published:
            if self.registration_required:
                registration_reminder_time = (self.registration_start -
                                              timezone.timedelta(hours=1))
                registration_reminder = ScheduledMessage()
                if (self.registration_reminder is not None
                        and not self.registration_reminder.sent):
                    registration_reminder = self.registration_reminder

                if registration_reminder_time > timezone.now():
                    registration_reminder.title_en = "Event registration"
                    registration_reminder.title_nl = "Evenement registratie"
                    registration_reminder.body_en = ("Registration for '{}' "
                                                     "starts in 1 hour".format(
                                                         self.title_en))
                    registration_reminder.body_nl = ("Registratie voor '{}' "
                                                     "start in 1 uur".format(
                                                         self.title_nl))
                    registration_reminder.category = Category.objects.get(
                        key=Category.EVENT)
                    registration_reminder.time = registration_reminder_time
                    registration_reminder.url = (
                        f"{settings.BASE_URL}"
                        f'{reverse("events:event", args=[self.id])}')

                    registration_reminder.save()
                    self.registration_reminder = registration_reminder
                    self.registration_reminder.users.set(
                        Member.current_members.all())
                elif registration_reminder.pk is not None:
                    delete_collector.add([self.registration_reminder])
                    self.registration_reminder = None

            start_reminder_time = self.start - timezone.timedelta(hours=1)
            start_reminder = ScheduledMessage()
            if self.start_reminder is not None and not self.start_reminder.sent:
                start_reminder = self.start_reminder

            if start_reminder_time > timezone.now():
                start_reminder.title_en = "Event"
                start_reminder.title_nl = "Evenement"
                start_reminder.body_en = f"'{self.title_en}' starts in " "1 hour"
                start_reminder.body_nl = f"'{self.title_nl}' begint over " "1 uur"
                start_reminder.category = Category.objects.get(
                    key=Category.EVENT)
                start_reminder.time = start_reminder_time
                start_reminder.save()
                self.start_reminder = start_reminder
                if self.registration_required:
                    self.start_reminder.users.set(
                        [r.member for r in self.participants if r.member])
                else:
                    self.start_reminder.users.set(Member.current_members.all())
            elif start_reminder.pk is not None:
                delete_collector.add([self.start_reminder])
                self.start_reminder = None
        else:
            if (self.registration_reminder is not None
                    and not self.registration_reminder.sent):
                delete_collector.add([self.registration_reminder])
                self.registration_reminder = None

            if self.start_reminder is not None and not self.start_reminder.sent:
                delete_collector.add([self.start_reminder])
                self.start_reminder = None

        super().save()
        delete_collector.delete()
예제 #33
0
    def delete(self):
        print("deleting ...") # debug
        count = self.count()
        for instance in self:
            
            print("get instance ...") # debug
            print(instance)
            instance_db = instance._state.db
            self_pk = instance.pk
            db = Databases.objects.get_data_by_full_name(instance._state.db)
            db.count = db.count - 1
            db.save()

            if instance.__class__.forward_models is not None:
                print("forward_fields", instance.__class__.forward_fields) # debug
                print("forward_models", instance.__class__.forward_models) # debug
                frd_pks = {}
                for forward_model in instance.__class__.forward_models:
                    attrname = instance.__class__.forward_fields[forward_model._meta.model_name]
                    frd_pks[getattr(instance, attrname + '_id')] = forward_model

            # 1- delete instance from its used database
            super(ShardUserModelQueryset,self).delete()

            # 2- same instance from related database:
            # forward_model ---> this instance
            if instance.__class__.forward_models is not None:
                for frd_pk in frd_pks:
     
                    forward_model = frd_pks[frd_pk]

                    print("forward model:", frd_pk, forward_model) # debug

                    ct_model = ContentType.objects.get(model=forward_model._meta.model_name).model_class()
                    ct_model_obj = ct_model.objects.filter(pk= frd_pk)

                    print("forward obj:", ct_model_obj) # debug

                    # do not delete forward_model instance if exist in its specific database
                    
                    if ct_model_obj.count() == 0:
                        qs = models.QuerySet(forward_model, using=str(instance_db)).filter(pk= frd_pk)
                        print(qs)           
                        collector = Collector(using=instance_db)
                        collector.collect(qs)
                        deleted, _rows_count = collector.delete()

            # 3- delete related model instance
            # related_model   --->    instance related to this model
            if instance.__class__.related_models is not None:
                print("get query set ...") # debug

                print("related models", instance.__class__.related_models) # debug
                

                for related_model in instance.related_models:
                    print("related fields", instance.related_fields[related_model._meta.model_name]) # debug

                    # get related database
                    db_list = Databases.objects.all().filter(model_name=related_model._meta.model_name).exclude(count=0)  
                    # if exist
                    if db_list.count() != 0:
                        for db in db_list:
                            #try: 

                                filters = {}
                                filters[instance.related_fields[related_model._meta.model_name]] = instance

                                qs1 = models.QuerySet(related_model, using=str(db)).filter(**filters)

                                # on delete cascad delete related instances
                                if self.model.on_delete[related_model._meta.model_name].__name__ == "CASCADE":

                                    collector = Collector(using=qs1.db)
                                    collector.collect(qs1)
                                    deleted, _rows_count = collector.delete()

                                if qs1.count() == 0:
                                    # if related instance dosn't exist
                                    # delete this model instance in other model databases 
                                    print("self_pk ", self_pk)
                                    qs2 = models.QuerySet(self.model, using=str(qs1.db)).filter(pk= self_pk)
                                    print('qs2', qs2)           
                                    collector = Collector(using=qs1.db)
                                    collector.collect(qs2)
                                    deleted, _rows_count = collector.delete()
예제 #34
0
    def delete(self):
        print("deleting ...")
        count = self.count()
        for instance in self:

            print("get instance ...") #debug
            print(instance) #debug
            db = Databases.objects.get_data_by_full_name(instance._state.db)
            instance_db = instance._state.db
            self_pk  = instance.pk
            db.count = db.count - 1
            db.save()
        
            if instance.__class__.forward_models is not None:
                print("forward_fields", instance.__class__.forward_fields) # debug
                print("forward_models", instance.__class__.forward_models) # debug
                frd_pks = {}
                for forward_model in instance.__class__.forward_models:
                    attrname = instance.__class__.forward_fields[forward_model._meta.model_name]
                    frd_pks[getattr(instance, attrname + '_id')] = forward_model


            # 1- delete instance from its used database
            super(ShardModelQueryset,self).delete()

            # 2- same instance from related database:
            if instance.__class__.forward_models is not None:
                for frd_pk in frd_pks:
     
                    forward_model = frd_pks[frd_pk]
                    print(frd_pk, forward_model)

                    ct_model = ContentType.objects.get(model=forward_model._meta.model_name).model_class()
                    ct_model_obj = ct_model.objects.filter(pk= frd_pk)

                    print(ct_model_obj)

                    # do not delete forward_model instance if exist in his specific database
                    if ct_model_obj.count() == 0:
                        qs = models.QuerySet(forward_model, using=str(instance_db)).filter(pk= frd_pk)
                        print(qs)           
                        collector = Collector(using=instance_db)
                        collector.collect(qs)
                        deleted, _rows_count = collector.delete()

            # 3- delete related model instance from its database:
            # related_models: mean models where use this model in
            # this mean when delete this model instance will delete 
            # also in other model databases
            if instance.__class__.related_models is not None:
                print("get query set ...")
                print(instance.__class__.related_models)
                for related_model in instance.related_models:
                
                    print(instance.related_fields)    
                    db_list = Databases.objects.all().filter(model_name=related_model._meta.model_name).exclude(count=0)  
                    if db_list.count() != 0:
                        for db in db_list:
                            try: 
                                # on delete cascad
                                # if self.model.on_delete[related_model._meta.model_name].__name__ == "CASCADE":
                                #     filters = {}
                                #     # TODO: Change key dynamicly 
                                #     filters["owner"] = instance

                                #     qs1 = models.QuerySet(related_model, using=str(db)).filter(**filters)

                                #     collector = Collector(using=qs1.db)
                                #     collector.collect(qs1)
                                #     deleted, _rows_count = collector.delete()

                                filters = {}

                                filters[instance.related_fields[related_model._meta.model_name]] = instance

                                qs1 = models.QuerySet(related_model, using=str(db)).filter(**filters)

                                # on delete cascad delete related instances
                                if self.model.on_delete[related_model._meta.model_name].__name__ == "CASCADE":

                                    collector = Collector(using=qs1.db)
                                    collector.collect(qs1)
                                    deleted, _rows_count = collector.delete()

                                if qs1.count() == 0:
                                    # if related instance dosn't exist
                                    # delete this model instance in other model databases 
                                    print("self_pk ", self_pk)
                                    qs2 = models.QuerySet(self.model, using=str(qs1.db)).filter(pk= self_pk)
                                    print('qs2', qs2)           
                                    collector = Collector(using=qs1.db)
                                    collector.collect(qs2)
                                    deleted, _rows_count = collector.delete()


                            except instance.DoesNotExist:
                                continue