Python django.db.models.signals.m2m_changed() Examples

The following are 9 code examples of django.db.models.signals.m2m_changed(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module django.db.models.signals , or try the search function .
Example #1
Source File: models.py    From clist with Apache License 2.0 6 votes vote down vote up
def update_account_url(signal, instance, **kwargs):

    def default_url():
        args = [instance.key, instance.resource.host]
        return reverse('coder:account', args=args)

    if signal is pre_save:
        if instance.url:
            return
        instance.url = default_url()
    elif signal is m2m_changed:
        if not kwargs.get('action').startswith('post_'):
            return
        url = None
        for coder in instance.coders.iterator():
            if url is not None:
                url = None
                break
            url = reverse('coder:profile', args=[coder.username]) + f'?search=resource:{instance.resource.host}'
        instance.url = url
        instance.save() 
Example #2
Source File: init-account-url.py    From clist with Apache License 2.0 6 votes vote down vote up
def run(*args):
    qs = Account.objects.filter(Q(url__isnull=True) | Q(coders__isnull=False))
    total = qs.count()
    iterator = qs.select_related('resource').prefetch_related('coders').iterator()
    with tqdm(total=total) as pbar:
        while True:
            with transaction.atomic():
                batch = 0
                for a in iterator:
                    update_account_url(m2m_changed, a, action='post_save')
                    pbar.update()
                    batch += 1
                    total -= 1
                    if batch == 10000:
                        break
                if batch == 0:
                    break 
Example #3
Source File: signals.py    From allianceauth with GNU General Public License v2.0 6 votes vote down vote up
def m2m_changed_user_groups(sender, instance, action, *args, **kwargs):
    logger.debug("Received m2m_changed from %s groups with action %s" % (instance, action))

    def trigger_service_group_update():
        logger.debug("Triggering service group update for %s" % instance)
        # Iterate through Service hooks
        for svc in ServicesHook.get_services():
            try:
                svc.validate_user(instance)
                svc.update_groups(instance)
            except:
                logger.exception('Exception running update_groups for services module %s on user %s' % (svc, instance))

    if instance.pk and (action == "post_add" or action == "post_remove" or action == "post_clear"):
        logger.debug("Waiting for commit to trigger service group update for %s" % instance)
        transaction.on_commit(trigger_service_group_update) 
Example #4
Source File: signals.py    From allianceauth with GNU General Public License v2.0 6 votes vote down vote up
def m2m_changed_user_permissions(sender, instance, action, *args, **kwargs):
    logger.debug("Received m2m_changed from user %s permissions with action %s" % (instance, action))
    logger.debug('sender: %s' % sender)
    if instance.pk and (action == "post_remove" or action == "post_clear"):
        logger.debug("Permissions changed for user {}, re-validating services".format(instance))
        # Checking permissions for a single user is quite fast, so we don't need to validate
        # That the permissions is a service permission, unlike groups.

        def validate_all_services():
            logger.debug("Validating all services for user {}".format(instance))
            for svc in ServicesHook.get_services():
                try:
                    svc.validate_user(instance)
                except:
                    logger.exception(
                        'Exception running validate_user for services module {} on user {}'.format(svc, instance))

        transaction.on_commit(lambda: validate_all_services()) 
Example #5
Source File: builder.py    From resolwe with Apache License 2.0 5 votes vote down vote up
def __init__(self, field):
        """Construct m2m dependency."""
        # We use None as the model as we cannot determine it until assigned to an index.
        super().__init__(None)

        self.accessor = None
        self.field = field
        # Cache for pre/post-remove action in m2m_changed signal.
        self.remove_cache = BuildArgumentsCache() 
Example #6
Source File: signals.py    From allianceauth with GNU General Public License v2.0 5 votes vote down vote up
def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwargs):
    logger.debug("Received m2m_changed from group %s permissions with action %s" % (instance, action))
    if instance.pk and (action == "post_remove" or action == "post_clear"):
        logger.debug("Checking if service permission changed for group {}".format(instance))
        # As validating an entire groups service could lead to many thousands of permission checks
        # first we check that one of the permissions changed is, in fact, a service permission.
        perms = Permission.objects.filter(pk__in=pk_set)
        got_change = False
        service_perms = [svc.access_perm for svc in ServicesHook.get_services()]
        for perm in perms:
            natural_key = perm.natural_key()
            path_perm = "{}.{}".format(natural_key[1], natural_key[0])
            if path_perm not in service_perms:
                # Not a service permission, keep searching
                continue
            for svc in ServicesHook.get_services():
                if svc.access_perm == path_perm:
                    logger.debug("Permissions changed for group {} on "
                                 "service {}, re-validating services for groups users".format(instance, svc))

                    def validate_all_groups_users_for_service():
                        logger.debug("Performing validation for service {}".format(svc))
                        for user in instance.user_set.all():
                            svc.validate_user(user)

                    transaction.on_commit(validate_all_groups_users_for_service)
                    got_change = True
                    break  # Found service, break out of services iteration and go back to permission iteration
        if not got_change:
            logger.debug("Permission change for group {} was not service permission, ignoring".format(instance)) 
Example #7
Source File: signals.py    From allianceauth with GNU General Public License v2.0 5 votes vote down vote up
def m2m_changed_state_permissions(sender, instance, action, pk_set, *args, **kwargs):
    logger.debug("Received m2m_changed from state %s permissions with action %s" % (instance, action))
    if instance.pk and (action == "post_remove" or action == "post_clear"):
        logger.debug("Checking if service permission changed for state {}".format(instance))
        # As validating an entire groups service could lead to many thousands of permission checks
        # first we check that one of the permissions changed is, in fact, a service permission.
        perms = Permission.objects.filter(pk__in=pk_set)
        got_change = False
        service_perms = [svc.access_perm for svc in ServicesHook.get_services()]
        for perm in perms:
            natural_key = perm.natural_key()
            path_perm = "{}.{}".format(natural_key[1], natural_key[0])
            if path_perm not in service_perms:
                # Not a service permission, keep searching
                continue
            for svc in ServicesHook.get_services():
                if svc.access_perm == path_perm:
                    logger.debug("Permissions changed for state {} on "
                                 "service {}, re-validating services for state users".format(instance, svc))

                    def validate_all_state_users_for_service():
                        logger.debug("Performing validation for service {}".format(svc))
                        for profile in instance.userprofile_set.all():
                            svc.validate_user(profile.user)

                    transaction.on_commit(validate_all_state_users_for_service)
                    got_change = True
                    break  # Found service, break out of services iteration and go back to permission iteration
        if not got_change:
            logger.debug("Permission change for state {} was not service permission, ignoring".format(instance)) 
Example #8
Source File: signals.py    From allianceauth with GNU General Public License v2.0 5 votes vote down vote up
def m2m_changed_authts_group(sender, instance, action, *args, **kwargs):
    logger.debug("Received m2m_changed from %s ts_group with action %s" % (instance, action))
    if action == "post_add" or action == "post_remove":
        transaction.on_commit(trigger_all_ts_update) 
Example #9
Source File: builder.py    From resolwe with Apache License 2.0 4 votes vote down vote up
def connect(self, index):
        """Connect signals needed for dependency updates."""
        # Determine which model is the target model as either side of the relation
        # may be passed as `field`.
        if index.object_type == self.field.rel.model:
            self.model = self.field.rel.related_model
            self.accessor = self.field.rel.field.attname
        else:
            self.model = self.field.rel.model
            if self.field.rel.symmetrical:
                # Symmetrical m2m relation on self has no reverse accessor.
                raise NotImplementedError(
                    "Dependencies on symmetrical M2M relations are not supported due "
                    "to strange handling of the m2m_changed signal which only makes "
                    "half of the relation visible during signal execution. For now you "
                    "need to use symmetrical=False on the M2M field definition."
                )
            else:
                self.accessor = self.field.rel.get_accessor_name()

        # Connect signals.
        signals = super().connect(index)

        m2m_signal = ElasticSignal(self, "process_m2m", pass_kwargs=True)
        m2m_signal.connect(m2m_changed, sender=self.field.through)
        signals.append(m2m_signal)

        # If the relation has a custom through model, we need to subscribe to it.
        if not self.field.rel.through._meta.auto_created:
            signal = ElasticSignal(self, "process_m2m_through_save", pass_kwargs=True)
            signal.connect(post_save, sender=self.field.rel.through)
            signals.append(signal)

            signal = ElasticSignal(
                self, "process_m2m_through_pre_delete", pass_kwargs=True
            )
            signal.connect(pre_delete, sender=self.field.rel.through)
            signals.append(signal)

            signal = ElasticSignal(
                self, "process_m2m_through_post_delete", pass_kwargs=True
            )
            signal.connect(post_delete, sender=self.field.rel.through)
            signals.append(signal)

        return signals