def clean(self): if self.model_object_id: # If the model object ID is specified, check that the instance with # this ID actually exists. try: object = self.model_content_type.get_object_for_this_type(pk = \ self.model_object_id) except ObjectDoesNotExist: raise ValidationError('Model instance with this ID does not exist') if self.action == get_choice_id('create', MODEL_ACTIONS): raise ValidationError('Model object ID must be empty when subscribing for a create event') if self.model_match_filter: # If the match filter is specified, check that it is valid if self.model_object_id and self.action == get_choice_id('delete', MODEL_ACTIONS): raise ValidationError('Model match filter must be empty when subscribing for a delete event on a specific model object') try: self.model_content_type except ObjectDoesNotExist: # No model selected yet return model_class = self.model_content_type.model_class() filter = MatchFilter(self.model_match_filter, model_class) if not filter.is_valid(): raise ValidationError('Invalid model match filter. Valid fields for this model are: %s' % (', ' . join(filter.valid_fields)))
def run(self, model, object_id, action, field_values): subscriptions = SubscriptionMap.objects.filter( subscription__model_content_type__model = model, \ subscription__action = action, \ subscription__active = True, active = True) for subscription in subscriptions: # Dispatch the notification tasks model_object_id = subscription.subscription.model_object_id match_filter = subscription.subscription.model_match_filter if model_object_id and (model_object_id != object_id): # Subscribed for an event on a single object, but the # object ID doesn't match. continue if match_filter: # This subscription has a model match filter defined. # Check if it matches model_class = subscription.subscription.model_content_type.model_class() filter = MatchFilter(match_filter, model_class) if not filter.matches(field_values): continue type = subscription.type subscriber = subscription.recipient field_values.update({'model': model, 'action': get_choice_id(action, MODEL_ACTIONS, \ reverse = True)}) if subscription.message: message = subscription.message.content template = Template(message) context = Context(field_values) message_rendered = template.render(context) else: message_rendered = field_values NotificationTask.delay(type, subscriber, message_rendered) if model_object_id and (action == get_choice_id('delete', MODEL_ACTIONS)): # Subscribed for delete event on a single object. # Subscription is de-activated after the notification task has been # dispatched. subscription.subscription.active = False subscription.subscription.save()