def register(cls, location=None): """ Register a model for translation like so: >>> from easymode import i18n >>> i18n.register(SomeModel) This will add entries to the gettext catalog located in the ``settings.LOCALE_DIR`` or directory. You can also store the catalogs somewhere else. The next example stores the catalog in the same dir as the file in which i18n.register is called: >>> i18n.register(SomeModel, __file__) You can also explictly give a path: >>> i18n.register(SomeModel, '/tmp/) Please note that the entire locale is stored in that path, so if the path is /tmp/ the locale is: /tmp/locale/ this directory will be created if it does not exist. :param cls: The model class that should be translated by means of gettext. :param location: The location of the po file. This can be either a directory\ or a file name. If left unspecified, ``settings.LOCALE_DIR`` or\ ``settings.PROJECT_DIR`` will be used. """ create_po_for_model = easymode.i18n.gettext.MakeModelMessages(location, cls) _post_save_handlers[cls] = create_po_for_model post_save.connect(create_po_for_model, cls, False)
def __init__(self, *args, **kwargs): super(DirtyFieldsMixin, self).__init__(*args, **kwargs) post_save.connect( reset_state, sender=self.__class__, dispatch_uid='{name}-DirtyFieldsMixin-sweeper'.format( name=self.__class__.__name__)) reset_state(sender=self.__class__, instance=self)
def update_image_sizes( sender, **kwargs): # if main image is too big, resize it; make a thumbnail image img_rec = kwargs.get('instance', None) if img_rec is None: return # (1) resize main image if img_rec.main_image.width > MAX_MAIN_IMAGE_WIDTH or img_rec.main_image.height > MAX_MAIN_IMAGE_WIDTH: im = Image.open(img_rec.main_image.file.name) # open image im.thumbnail((MAX_MAIN_IMAGE_WIDTH, MAX_MAIN_IMAGE_WIDTH), Image.ANTIALIAS) # resize im.save(img_rec.main_image.file.name, quality=90) #save # (2) make a thumbnail thumb = Image.open(img_rec.main_image.file.name) # open the main image thumb.thumbnail((MAX_THUMB_IMAGE_WIDTH, MAX_THUMB_IMAGE_WIDTH), Image.ANTIALIAS) thumb_fullpath = os.path.join(settings.MEDIA_ROOT\ , img_rec.get_image_upload_directory_thumb(os.path.basename(img_rec.main_image.path)) ) # if needed, make thumb directory if not os.path.isdir(os.path.dirname(thumb_fullpath)): os.makedirs(os.path.dirname(thumb_fullpath)) # save file thumb.save(thumb_fullpath, quality=100) # disconnect save signal, save the ImageRecord, and reconnect signal post_save.disconnect(ImageRecord.update_image_sizes, sender=ImageRecord) # update/save django model img_rec.thumb_image.name = img_rec.get_image_upload_directory_thumb(os.path.basename(thumb_fullpath)) img_rec.save() post_save.connect(ImageRecord.update_image_sizes, sender=ImageRecord)
def register(self, model_class, fields=None, follow=(), format=DEFAULT_SERIALIZATION_FORMAT): """Registers a model with this revision manager.""" # Prevent multiple registration. if self.is_registered(model_class): raise RegistrationError, "%r has already been registered with Reversion." % model_class # Ensure the parent model of proxy models is registered. if model_class._meta.proxy and not self.is_registered(model_class._meta.parents.keys()[0]): raise RegistrationError, "%r is a proxy model, and its parent has not been registered with Reversion." % model_class # Calculate serializable model fields. opts = model_class._meta local_fields = opts.local_fields + opts.local_many_to_many if fields is None: fields = [field.name for field in local_fields] fields = tuple(fields) # Calculate serializable model file fields. file_fields = [] for field in local_fields: if isinstance(field, models.FileField) and field.name in fields: field.storage = VersionFileStorageWrapper(field.storage) file_fields.append(field) file_fields = tuple(file_fields) # Register the generated registration information. follow = tuple(follow) registration_info = RegistrationInfo(fields, file_fields, follow, format) self._registry[model_class] = registration_info # Connect to the post save signal of the model. post_save.connect(self.post_save_receiver, model_class)
def connect_signals(cls): # Call _post_save every time one of cls.MODELS is saved. for model in cls.MODELS: post_save.connect( cls._post_save, sender=model)
def contribute_to_class(self, cls, name): """ Add each of the names and fields in the ``fields`` attribute to the model the relationship field is applied to, and set up the related item save and delete signals for calling ``related_items_changed``. """ for field in cls._meta.many_to_many: if isinstance(field, self.__class__): e = "Multiple %s fields are not supported (%s.%s, %s.%s)" % ( self.__class__.__name__, cls.__name__, cls.__name__, name, field.name) raise ImproperlyConfigured(e) self.related_field_name = name super(BaseGenericRelation, self).contribute_to_class(cls, name) # Not applicable to abstract classes, and in fact will break. if not cls._meta.abstract and not self.frozen_by_south: for (name_string, field) in self.fields.items(): if "%s" in name_string: name_string = name_string % name if not field.verbose_name: field.verbose_name = self.verbose_name cls.add_to_class(name_string, copy(field)) # Add a getter function to the model we can use to retrieve # the field/manager by type without knowing its name. getter_name = "get_%s_manager" % self.__class__.__name__.lower() cls.add_to_class(getter_name, lambda s: getattr(s, name)) # For some unknown reason the signal won't be triggered # if given a sender arg, particularly when running # Cartridge with the field RichTextPage.keywords - so # instead of specifying self.rel.to as the sender, we # check for it inside the signal itself. post_save.connect(self._related_items_changed) post_delete.connect(self._related_items_changed)
def tearDown(self): version_changed_signal.connect(version_changed, dispatch_uid='version_changed') post_save.connect(update_status, sender=Version, dispatch_uid='version_update_status') post_delete.connect(update_status, sender=Version, dispatch_uid='version_update_status')
def test_username_updated_successfully(self, logger_mock): """ Test that the command updates the user's username when the user is linked to an Enterprise. """ user = User.objects.create(is_active=True, username='******', email='*****@*****.**') site, _ = Site.objects.get_or_create(domain='example.com') enterprise_customer = EnterpriseCustomer.objects.create( name='Test EnterpriseCustomer', site=site ) EnterpriseCustomerUser.objects.create( user_id=user.id, enterprise_customer=enterprise_customer ) new_username = '******' post_save_handler = mock.MagicMock() post_save.connect(post_save_handler, sender=User) call_command(self.command, user_id=user.id, new_username=new_username) logger_mock.info.assert_called_with('User {} has been updated with username {}.'.format(user.id, new_username)) post_save_handler.assert_called() updated_user = User.objects.get(id=user.id) assert updated_user.username == new_username
def register(self, model=None, adapter_cls=VersionAdapter, **field_overrides): """Registers a model with this revision manager.""" # Return a class decorator if model is not given if model is None: return partial(self.register, adapter_cls=adapter_cls, **field_overrides) # Prevent multiple registration. if self.is_registered(model): raise RegistrationError("{model} has already been registered with django-reversion".format( model = model, )) # Prevent proxy models being registered. if model._meta.proxy: raise RegistrationError( "{model} is a proxy model, and cannot be used with django-reversion, register the parent class ({model_parent}) instead.".format( # noqa model=model.__name__, model_parent=', '.join( [x.__name__ for x in model._meta.parents.keys()]) )) # Perform any customization. if field_overrides: adapter_cls = type(adapter_cls.__name__, (adapter_cls,), field_overrides) # Perform the registration. adapter_obj = adapter_cls(model) self._registered_models[self._registration_key_for_model(model)] = adapter_obj # Connect to the post save signal of the model. post_save.connect(self._post_save_receiver, model) return model
def __init__(self, *args, **kwargs): self.mandatory_vars.append('scraped_obj_class') self.mandatory_vars.append('scraped_obj_item_class') super(DjangoSpider, self).__init__(self, *args, **kwargs) self._set_config(**kwargs) self._set_request_kwargs() for cp_path in self.conf['CUSTOM_PROCESSORS']: try: custom_processors = importlib.import_module(cp_path) except ImportError: msg = "Custom processors from {path} could not be imported, processors won't be applied".format( path=cp_path, ) self.log(msg, logging.WARNING) post_save.connect(self._post_save_tasks, sender=self.scraped_obj_class) self._set_start_urls(self.scrape_url) self.scheduler = Scheduler(self.scraper.scraped_obj_class.scraper_scheduler_conf) self.from_page = 'MP' self.loader = None self.dummy_loader = None self.items_read_count = 0 self.items_save_count = 0 msg = 'Spider for {roc} "{ro}" ({pk}) initialized.'.format( roc=self.ref_object.__class__.__name__, ro=str(self.ref_object), pk=str(self.ref_object.pk), ) self.log(msg, logging.INFO)
def register_live_index(model_cls): """Register a model and index for auto indexing.""" uid = str(model_cls) + 'live_indexing' post_save.connect(_live_index_handler, model_cls, dispatch_uid=uid) pre_delete.connect(_live_index_handler, model_cls, dispatch_uid=uid) # Enable this to be used as decorator. return model_cls
def register(model, fields, restrict_to=None, manager=None): """Tell vinaigrette which fields on a Django model should be translated. Arguments: model -- The relevant model class fields -- A list or tuple of field names. e.g. ['name', 'nickname'] restrict_to -- Optional. A django.db.models.Q object representing the subset of objects to collect translation strings from. manager -- Optional. A reference to a manager -- e.g. Person.objects -- to use when collecting translation strings. Note that both restrict_to and manager are only used when collecting translation strings. Gettext lookups will always be performed on relevant fields for all objects on registered models. """ global _registry _registry[model] = { 'fields': fields, 'restrict_to': restrict_to, 'manager': manager } for field in fields: setattr(model, field, VinaigretteDescriptor(field)) model.untranslated = lambda self, fieldname: self.__dict__[fieldname] pre_save.connect(_vinaigrette_pre_save, sender=model) post_save.connect(_vinaigrette_post_save, sender=model)
def ready(self): # Load projector elements. # Do this by just importing all from these files. from . import projector # noqa # Import all required stuff. from django.db.models.signals import pre_delete, post_save from openslides.core.config import config from openslides.utils.rest_api import router from .config_variables import get_config_variables from .signals import ( listen_to_related_object_post_delete, listen_to_related_object_post_save) from .views import ItemViewSet # Define config variables config.update_config_variables(get_config_variables()) # Connect signals. post_save.connect( listen_to_related_object_post_save, dispatch_uid='listen_to_related_object_post_save') pre_delete.connect( listen_to_related_object_post_delete, dispatch_uid='listen_to_related_object_post_delete') # Register viewsets. router.register(self.get_model('Item').get_collection_string(), ItemViewSet)
def _run_listen(): post_save.connect(run_watchers.post_run_saved, sender=TestRun) post_save.connect(run_watchers.post_case_run_saved, sender=TestCaseRun, dispatch_uid='tcms.testruns.models.TestCaseRun') post_delete.connect(run_watchers.post_case_run_deleted, sender=TestCaseRun, dispatch_uid='tcms.testruns.models.TestCaseRun') pre_save.connect(run_watchers.pre_save_clean, sender=TestRun)
def register(self, model, adapter_cls=SearchAdapter, **field_overrides): """ Registers the given model with this search engine. If the given model is already registered with this search engine, a RegistrationError will be raised. """ # Add in custom live filters. if isinstance(model, QuerySet): live_queryset = model model = model.model field_overrides["get_live_queryset"] = lambda self_: live_queryset.all() # Check for existing registration. if self.is_registered(model): raise RegistrationError("{model!r} is already registered with this search engine".format( model = model, )) # Perform any customization. if field_overrides: # Conversion to str is needed because Python 2 doesn't accept unicode for class name adapter_cls = type(str("Custom") + adapter_cls.__name__, (adapter_cls,), field_overrides) # Perform the registration. adapter_obj = adapter_cls(model) self._registered_models[model] = adapter_obj # Connect to the signalling framework. post_save.connect(self._post_save_receiver, model) pre_delete.connect(self._pre_delete_receiver, model)
def from_crawler(cls, crawler, *args, **kwargs): spider = cls(*args, **kwargs) spider._set_crawler(crawler) spider._set_config(**kwargs) spider._set_request_kwargs() for cp_path in spider.conf['CUSTOM_PROCESSORS']: try: custom_processors = importlib.import_module(cp_path) except ImportError: msg = "Custom processors from {path} could not be imported, processors won't be applied".format( path=cp_path, ) spider.log(msg, logging.WARNING) post_save.connect(spider._post_save_tasks, sender=spider.scraped_obj_class) spider._set_start_urls(spider.scrape_url) spider.scheduler = Scheduler(spider.scraper.scraped_obj_class.scraper_scheduler_conf) spider.from_page = 'MP' spider.loader = None spider.dummy_loader = None spider.items_read_count = 0 spider.items_save_count = 0 msg = 'Spider for {roc} "{ro}" ({pk}) initialized.'.format( roc=spider.ref_object.__class__.__name__, ro=str(spider.ref_object), pk=str(spider.ref_object.pk), ) spider.log(msg, logging.INFO) return spider
def update_have_analogues(sender, instance, **kwargs): instance.have_analogues = bool(instance.analogues.count()) post_save.disconnect(Product.update_have_analogues, sender=Product) for analogue in instance.analogues.all(): analogue.have_analogues = bool(analogue.analogues.count()) analogue.save() post_save.connect(Product.update_have_analogues, sender=Product)
def register_post_save_functions(): # Disconnect first in case this function is called twice logger.debug('Thumbnail: Registering post_save functions.') post_save.disconnect(generate_thumbnail, sender=Layer) post_save.connect(generate_thumbnail, sender=Layer, weak=False) post_save.disconnect(generate_thumbnail, sender=Map) post_save.connect(generate_thumbnail, sender=Map, weak=False)
def registerInstagramListener(**kwargs): ''' Trigger that is invoked when a hashtag is registered or updated using the model save method ''' instance = kwargs['instance'] object_type = instance.object_type object_value = instance.object_value callback_url = "{0}/instagramPush/{1}".format(CALLBACK_HOST, instance.id) res = None if object_type == "geography": res = api.create_subscription( object=object_type, aspect='media', lat=instance.lat, lng=instance.lng, radius=instance.radius, callback_url=callback_url ) elif object_type == "user": print "Handling user" user_res = api.user_search(q=object_value, count=1) user_id = [ i.id for i in user_res if i.username == object_value][0] object_value = user_id res = api.create_subscription( object=object_type, object_id=user_id, aspect='media', callback_url=callback_url ) else: res = api.create_subscription( object=object_type, object_id=object_value, aspect='media', callback_url=callback_url ) #Disconnect the handler so we don't fall into endless loop post_save.disconnect(registerInstagramListener, sender=Subscription) instance.remote_id = res['data']['id'] instance.save() post_save.connect(registerInstagramListener, sender=Subscription) #Populate the subscription with recent media update = {'object':object_type,'object_id':object_value, 'subscription_id': instance.remote_id } processInstagramUpdate(update)
def save(self, uid, content, username, commit_msg, save): def savefile(sender, instance=None, **kwargs): # check that the instance is the right one try: saved_uid = getattr(instance, self.fieldname).name except AttributeError: # an instance of another class return if saved_uid != uid: return # create the actual filename from the versioned file name = self.backend.get_filename(instance) content.name = name # new revision self.backend.add_revision(content, instance, commit_msg, username) if save or kwargs['created']: setattr(instance, self.fieldname, name) instance.save() # remove signal post_save.disconnect(dispatch_uid=uid) post_save.connect(savefile, weak=False, dispatch_uid=uid) return force_text(uid.replace('\\', '/'))
def _pre_setup(self): super(ReputationTestCase, self)._pre_setup() self.reputations = {} post_save.connect( self.record_tine_profile_reputation, sender=TineProfile )
def __init__(self, model, field, expected_value, handler): def wrapper(instance, **kwargs): dirty_fields = instance.get_dirty_fields() if field in dirty_fields and instance.__dict__[field] == expected_value: handler(instance=instance) post_save.connect(wrapper, sender=model, weak=False)
def register(self, model_or_iterable, search_class=None, **options): """ Registers the given model(s) with the given search class. The model(s) should be Model classes, not instances. If an search class isn't given, it will use ModelSearch (the default search options). If keyword arguments are given -- e.g., exclude -- they'll be applied as options to the search class. If a model is already registered, this will raise AlreadyRegistered. """ if not search_class: search_class = ModelSearch if isinstance(model_or_iterable, ModelBase): model_or_iterable = [model_or_iterable] for model in model_or_iterable: if model in self._registry: raise AlreadyRegistered("The model %s is already registered" % model.__name__) # If we got **options then dynamically construct a subclass of # search_class with those **options. if options: # For reasons I don't quite understand, without a __module__ # the created class appears to "live" in the wrong place, # which causes issues later on. options["__module__"] = __name__ search_class = type("%sSearch" % model.__name__, (search_class,), options) self._registry[model] = search_class(model, self) # Attache post_save and post_delete signals post_save.connect(self._registry[model].post_save_callback, sender=model) post_delete.connect(self._registry[model].post_delete_callback, sender=model)
def ready(self): post_save.connect( self.cache_last_handler, sender='issues_log.LogEntry', weak=False, dispatch_uid='issues_log.cache_last_handler', )
def ready(self): RabbitWorker().declare_exchange() from models import Collection, Export from sched import start_sched, schedule_harvest_receiver, unschedule_harvest_receiver from export import export_receiver, export_m2m_receiver from notifications import send_user_harvest_emails if settings.SCHEDULE_HARVESTS: log.debug("Setting receivers for collections.") post_save.connect(schedule_harvest_receiver, sender=Collection) pre_delete.connect(unschedule_harvest_receiver, sender=Collection) # Export if settings.PERFORM_EXPORTS: log.debug("Setting receiver for exports.") post_save.connect(export_receiver, sender=Export) m2m_changed.connect(export_m2m_receiver, sender=Export.seeds.through) # Add 5 minute interval if settings.FIVE_MINUTE_SCHEDULE: log.debug("Adding 5 minute timer") Collection.SCHEDULE_CHOICES.append((5, "Every 5 minutes")) if settings.RUN_SCHEDULER: log.debug("Running scheduler") sched = start_sched() if settings.PERFORM_USER_HARVEST_EMAILS: if sched.get_job('user_harvest_emails') is not None: sched.remove_job('user_harvest_emails') sched.add_job(send_user_harvest_emails, 'cron', hour=settings.USER_HARVEST_EMAILS_HOUR, minute=settings.USER_HARVEST_EMAILS_MINUTE, id='user_harvest_emails') else: log.debug("Not running scheduler")
def contribute_to_class(self, cls, name): """ Add each of the names and fields in the ``fields`` attribute to the model the relationship field is applied to, and set up the related item save and delete signals for calling ``related_items_changed``. """ for field in cls._meta.many_to_many: if isinstance(field, self.__class__): e = "Multiple %s fields are not supported (%s.%s, %s.%s)" % ( self.__class__.__name__, cls.__name__, cls.__name__, name, field.name) raise ImproperlyConfigured(e) self.related_field_name = name super(BaseGenericRelation, self).contribute_to_class(cls, name) # Not applicable to abstract classes, and in fact will break. if not cls._meta.abstract: for (name_string, field) in self.fields.items(): if "%s" in name_string: name_string = name_string % name extant_fields = cls._meta._forward_fields_map if name_string in extant_fields: continue if field.verbose_name is None: field.verbose_name = self.verbose_name cls.add_to_class(name_string, copy(field)) # Add a getter function to the model we can use to retrieve # the field/manager by name. getter_name = "get_%s_name" % self.__class__.__name__.lower() cls.add_to_class(getter_name, lambda self: name) sender = self.rel.to post_save.connect(self._related_items_changed, sender=sender) post_delete.connect(self._related_items_changed, sender=sender)
def register(cls, admin_cls): cls.add_to_class('_ct_inventory', JSONField(_('content types'), editable=False, blank=True, null=True)) cls.content_proxy_class = TrackerContentProxy pre_save.connect(single_pre_save_handler, sender=cls) if hasattr(cls, 'get_descendants'): post_save.connect(tree_post_save_handler, sender=cls)
def _attach_signals(self): ''' Attach all signals for eav ''' post_init.connect(Registry.attach_eav_attr, sender=self.model_cls) pre_save.connect(Entity.pre_save_handler, sender=self.model_cls) post_save.connect(Entity.post_save_handler, sender=self.model_cls)
def create_user(backend, details, response, uid, username, user=None, *args, **kwargs): """Create user. Depends on get_username pipeline.""" if user: return {'user': user} if not username: return None email = details.get('email') name = response.get('name') if name: # if they already have a profile created for them, use that profile try: master_user = User.objects.get(username='******') profile = Profile.objects.get(name=name, user=master_user) except Profile.DoesNotExist: pass else: logger.info('Using existing profile for social-auth with name {0}'.format(profile.name)) post_save.disconnect(create_profile, sender=User) user = User.objects.create_user(username=username, email=email) post_save.connect(create_profile, sender=User) # in case we already associated by email to an existing account and profile... if not Profile.objects.filter(user=user).count(): profile.user = user profile.save() if not user: user = User.objects.create_user(username=username, email=email) return { 'user': user, 'is_new': True }
def cache_model(model, timeout=None): """ Adds utility methods to the given model to obtain ``ForeignKey`` instances via the cache. """ if hasattr(model, 'get_cached'): # Already patched return def clear_cache(sender, instance, *args, **kwargs): # pylint: disable=unused-argument """ Clears the cache for the given instance. """ delete_instance(sender, instance) post_save.connect(clear_cache, sender=model, weak=False) post_delete.connect(clear_cache, sender=model, weak=False) @classmethod def get(cls, pk, using=None): # pylint: disable=invalid-name """ Returns the model for the given primary key (pk). """ if pk is None: return None return get_instance(cls, pk, timeout, using) model.get_cached = get
str = __unicode__ def url(self): return "%s%s" % (settings.BANNERS_URL, self.image) def is_flash(self): return str(self.image)[-4:].lower() == '.swf' def invalidate_banners_cache(sender, **kw): for k in BannerGroup.objects.all(): print "CALL SIGNAL:", "bannerscachett_%s" % k.name cache.delete("bannerscachett_%s" % k.name) post_save.connect(invalidate_banners_cache, sender=Banner) pre_delete.connect(invalidate_banners_cache, sender=Banner) post_save.connect(invalidate_banners_cache, sender=BannerGroup) pre_delete.connect(invalidate_banners_cache, sender=BannerGroup) class TextBanner(models.Model): title = models.CharField(u"Название баннера", max_length=200, null=False, blank=False) effective_date = models.DateTimeField(u"Дата вступления в силу") expire_date = models.DateTimeField(u"Дата истечения срока действия", null=True, blank=True)
from django.db.models.signals import post_save def create_default_per_instance_preferences(sender, created, instance, **kwargs): """Create default preferences for PerInstancePreferenceModel""" if created: try: registry = preference_models.get_by_instance(instance) registry.create_default_preferences(instance) except AttributeError: pass def invalidate_cache(sender, created, instance, **kwargs): if not isinstance(instance, BasePreferenceModel): return registry = preference_models.get_by_preference(instance) linked_instance = getattr(instance, 'instance', None) kwargs = {} if linked_instance: kwargs['instance'] = linked_instance manager = registry.manager(**kwargs) manager.to_cache(instance) post_save.connect(create_default_per_instance_preferences) post_save.connect(invalidate_cache)
def ready(self): super(CommonApp, self).ready() APIEndPoint(app=self, version_string='1') app.conf.CELERYBEAT_SCHEDULE.update({ 'task_delete_stale_uploads': { 'task': 'common.tasks.task_delete_stale_uploads', 'schedule': timedelta(seconds=DELETE_STALE_UPLOADS_INTERVAL), }, }) app.conf.CELERY_QUEUES.extend(( Queue('default', Exchange('default'), routing_key='default'), Queue('tools', Exchange('tools'), routing_key='tools'), Queue('common_periodic', Exchange('common_periodic'), routing_key='common_periodic', delivery_mode=1), )) app.conf.CELERY_DEFAULT_QUEUE = 'default' app.conf.CELERY_ROUTES.update({ 'common.tasks.task_delete_stale_uploads': { 'queue': 'common_periodic' }, }) menu_user.bind_links(links=(Text(text=CommonApp.get_user_label_text), Separator(), link_current_user_details, link_current_user_edit, link_current_user_locale_profile_edit, Separator())) menu_about.bind_links(links=( link_tools, link_setup, link_about, # link_support, #link_documentation, link_forum, link_code, link_license, link_packages_licenses #, link_check_version )) menu_main.bind_links(links=( menu_about, menu_user, ), position=99) menu_secondary.bind_links(links=(link_object_error_list_clear, ), sources=('common:object_error_list', )) #menu_tools.bind_links( # links=(link_filters,) #) post_save.connect(user_locale_profile_create, dispatch_uid='user_locale_profile_create', sender=settings.AUTH_USER_MODEL) pre_initial_setup.connect( handler_pre_initial_setup, dispatch_uid='common_handler_pre_initial_setup') pre_upgrade.connect( handler_pre_upgrade, dispatch_uid='common_handler_pre_upgrade', ) user_logged_in.connect( user_locale_profile_session_config, dispatch_uid='user_locale_profile_session_config') self.setup_auto_logging()
m2m_changed.connect(emit_update_inventory_computed_fields, sender=Host.inventory_sources.through) m2m_changed.connect(emit_update_inventory_computed_fields, sender=Group.inventory_sources.through) post_save.connect(emit_update_inventory_on_created_or_deleted, sender=InventorySource) post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=InventorySource) post_save.connect(emit_update_inventory_on_created_or_deleted, sender=Job) post_delete.connect(emit_update_inventory_on_created_or_deleted, sender=Job) connect_computed_field_signals() post_save.connect(emit_job_event_detail, sender=JobEvent) post_save.connect(emit_ad_hoc_command_event_detail, sender=AdHocCommandEvent) post_save.connect(emit_project_update_event_detail, sender=ProjectUpdateEvent) post_save.connect(emit_inventory_update_event_detail, sender=InventoryUpdateEvent) post_save.connect(emit_system_job_event_detail, sender=SystemJobEvent) m2m_changed.connect(rebuild_role_ancestor_list, Role.parents.through) m2m_changed.connect(org_admin_edit_members, Role.members.through) m2m_changed.connect(rbac_activity_stream, Role.members.through) m2m_changed.connect(rbac_activity_stream, Role.parents.through) post_save.connect(sync_superuser_status_to_rbac, sender=User) post_save.connect(create_user_role, sender=User) pre_delete.connect(cleanup_detached_labels_on_deleted_parent, sender=UnifiedJob) pre_delete.connect(cleanup_detached_labels_on_deleted_parent, sender=UnifiedJobTemplate)
def remove(self): return '?pk=%s&delete=True' %(self.pk) def create_payee_post_save_receiver(sender, instance, created, *args, **kwargs): if created: if instance.rank == "替代役": new_payee, create = Payee.objects.get_or_create(name=instance.name, identity=instance.pk) try: payee = Payee.objects.get(identity=instance.pk) payee.name = instance.name payee.save() except: pass post_save.connect(create_payee_post_save_receiver, sender=UserProfile) def delete_payee_post_delete_receiver(sender, instance, *args, **kwargs): try: payee = Payee.objects.get(identity=instance.pk) payee.delete() except: pass post_delete.connect(delete_payee_post_delete_receiver, sender=UserProfile) class Payee(models.Model): name = models.CharField(max_length=20) identity = models.IntegerField()
('initial', 'Initial'), ('qualification', 'Qualification'), ('presentation', 'Presentation'), ('evaluation', 'Evaluation'), ('closing', 'Closing') ) class CustomerStatus(models.Model): company_name = models.ForeignKey(CustomerInformation) stage = models.CharField(max_length=120, choices=STAGES, default='Initial') deal_size = models.DecimalField(max_digits=50, decimal_places=2, blank=True, null=True) follow_up_task = models.CharField(max_length=120, blank=True, null=True) follow_up_date = models.DateField(null=True, blank=True) def __str__(self): return str(self.company_name.id) def save_customerstatus(sender, instance, *args, **kwargs): customer_status = instance.customerstatus_set.all() if customer_status.count() == 0: status = CustomerStatus() status.company_name = instance status.stage = 'Initial' status.deal_size = 0.00 status.save() post_save.connect(save_customerstatus, sender=CustomerInformation)
else: pass def DeleteBasket(sender, instance, **kworgs): try: new_b = Basket.objects.get(user=instance) new_b.delete() print('Basket was deleted!') except: pass else: pass post_save.connect(CreateBasket, sender=User) post_delete.connect(DeleteBasket, sender=User) class BasketsItem(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) product = models.ForeignKey("Product", on_delete=models.CASCADE) num = models.IntegerField() def __str__(self): return f'{self.product}' class Product(models.Model): name = models.TextField() description = models.TextField()
Bw_balls = models.IntegerField(default=0) Bw_wickets = models.IntegerField(default=0) def __str__(self): return "{}".format(self.player_id) @receiver(post_save, sender=player_info) def create_player_objects(sender, **kwargs): if kwargs['created']: player_batting = batting.objects.create(player_id=kwargs['instance']) player_bowling = bowling.objects.create(player_id=kwargs['instance']) # post_save.connect(create_player_objects, sender=player_info) def create_points_table(sender, **kwargs): if kwargs['created']: team_points_table = points_table.objects.create(team_id=kwargs['instance']) post_save.connect(create_points_table, sender=Team) class playing_XI(models.Model): palyer_choices = ( ('VK', 'Virat Kohli'), ('ST', 'Sachin'), ('RS', 'Rohit Sharma'), ('MS', 'Mohammed Shami'), ) players = MultiSelectField(choices = palyer_choices, max_choices=2)
abstract = True def to_search(self): return { 'owner': self.owner.to_search(), 'creation_date': self.creation_date, 'popularity': self.score, 'text': self.text, } class QuestionComment(Comment): post = models.ForeignKey(Question, related_name='comment_set') class AnswerComment(Comment): post = models.ForeignKey(Answer, related_name='comment_set') def update_search(instance, **kwargs): instance.to_search().save() def remove_from_search(instance, **kwargs): instance.to_search().delete() post_save.connect(update_search, sender=Answer) post_save.connect(update_search, sender=Question) pre_delete.connect(remove_from_search, sender=Answer) pre_delete.connect(remove_from_search, sender=Question)
faculty.teacher = True faculty.save() def create_faculty_profile(sender, instance, created, **kwargs): if instance.groups.filter(name="teacher").count(): create_faculty(instance) def create_faculty_profile_m2m(sender, instance, action, reverse, model, pk_set, **kwargs): if action == 'post_add' and instance.groups.filter(name="teacher").count(): create_faculty(instance) post_save.connect(create_faculty_profile, sender=User) m2m_changed.connect(create_faculty_profile_m2m, sender=User.groups.through) class UserPreference(models.Model): """ User Preferences """ file_format_choices = ( ('o', 'Open Document Format (.odt, .ods)'), ('m', 'Microsoft Binary (.doc, .xls)'), ('x', 'Microsoft Office Open XML (.docx, .xlsx) Not recommended, formatting may be lost!' ), ) prefered_file_format = models.CharField( default=settings.PREFERED_FORMAT, max_length="1",
job_title = models.CharField(max_length=100, null=False, blank=False) job_desc = models.CharField(max_length=100, null=False, blank=False) skills_required = MultiSelectField(choices=skills) education = MultiSelectField(choices=ed) education_years = models.IntegerField(blank=False, null=False) vacancy = models.IntegerField(blank=True, null=True) def __str__(self): return self.job_title class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') company_id = models.ForeignKey(to=company, on_delete=models.CASCADE, null=True, blank=True) @receiver(post_save, sender=User) def create_profile_for_user(sender, instance, created, **kwargs): if created: profile = Profile.objects.get_or_create(user=instance) instance.profile.save() post_save.connect(create_profile_for_user, sender=User)
def ready(self): super(DocumentIndexingApp, self).ready() Document = apps.get_model(app_label='documents', model_name='Document') DocumentType = apps.get_model(app_label='documents', model_name='DocumentType') DocumentMetadata = apps.get_model(app_label='metadata', model_name='DocumentMetadata') DocumentIndexInstanceNode = self.get_model('DocumentIndexInstanceNode') Index = self.get_model('Index') IndexInstance = self.get_model('IndexInstance') IndexInstanceNode = self.get_model('IndexInstanceNode') IndexTemplateNode = self.get_model('IndexTemplateNode') APIEndPoint(app=self, version_string='1') ModelPermission.register(model=Index, permissions=( permission_acl_edit, permission_acl_view, permission_document_indexing_create, permission_document_indexing_delete, permission_document_indexing_edit, permission_document_indexing_view, )) SourceColumn(source=Index, label=_('Label'), attribute='label') SourceColumn(source=Index, label=_('Slug'), attribute='slug') SourceColumn( source=Index, label=_('Enabled'), func=lambda context: two_state_template(context['object'].enabled)) SourceColumn(source=IndexInstance, label=_('Items'), func=lambda context: context['object'].get_item_count( user=context['request'].user)) SourceColumn(source=IndexInstance, label=_('Document types'), attribute='get_document_types_names') SourceColumn(source=IndexTemplateNode, label=_('Level'), func=lambda context: node_level(context['object'])) SourceColumn( source=IndexTemplateNode, label=_('Enabled'), func=lambda context: two_state_template(context['object'].enabled)) SourceColumn(source=IndexTemplateNode, label=_('Has document links?'), func=lambda context: two_state_template(context['object']. link_documents)) SourceColumn( source=IndexInstanceNode, label=_('Node'), func=lambda context: index_instance_item_link(context['object'])) SourceColumn(source=IndexInstanceNode, label=_('Items'), func=lambda context: context['object'].get_item_count( user=context['request'].user)) SourceColumn(source=DocumentIndexInstanceNode, label=_('Node'), func=lambda context: get_instance_link( index_instance_node=context['object'], )) SourceColumn(source=DocumentIndexInstanceNode, label=_('Items'), func=lambda context: context['object'].get_item_count( user=context['request'].user)) app.conf.CELERY_QUEUES.append( Queue('indexing', Exchange('indexing'), routing_key='indexing'), ) app.conf.CELERY_ROUTES.update({ 'document_indexing.tasks.task_delete_empty_index_nodes': { 'queue': 'indexing' }, 'document_indexing.tasks.task_index_document': { 'queue': 'indexing' }, 'document_indexing.tasks.task_do_rebuild_all_indexes': { 'queue': 'tools' }, }) menu_facet.bind_links(links=(link_document_index_list, ), sources=(Document, )) menu_object.bind_links(links=(link_index_setup_edit, link_index_setup_view, link_index_setup_document_types, link_acl_list, link_index_setup_delete), sources=(Index, )) menu_object.bind_links(links=(link_template_node_create, link_template_node_edit, link_template_node_delete), sources=(IndexTemplateNode, )) menu_main.bind_links(links=(link_index_main_menu, ), position=98) menu_secondary.bind_links(links=(link_index_setup_list, link_index_setup_create), sources=(Index, 'indexing:index_setup_list', 'indexing:index_setup_create')) menu_setup.bind_links(links=(link_index_setup, )) menu_tools.bind_links(links=(link_rebuild_index_instances, )) post_delete.connect(document_index_delete, dispatch_uid='document_index_delete', sender=Document) post_delete.connect(document_metadata_index_post_delete, dispatch_uid='document_metadata_index_post_delete', sender=DocumentMetadata) post_document_created.connect( document_created_index_update, dispatch_uid='document_created_index_update', sender=Document) post_initial_document_type.connect( create_default_document_index, dispatch_uid='create_default_document_index', sender=DocumentType) post_save.connect(document_metadata_index_update, dispatch_uid='document_metadata_index_update', sender=DocumentMetadata)
from django.conf import settings from django.db.models.signals import post_save from django.db import models class Profile(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) bio = models.TextField(blank=True) website_url = models.URLField(blank=True) def on_post_save_for_user( sender, **kwargs): # kwargs에는 instance와 created라는 이름의 인자가 담겨서 온다 if kwargs['created']: # 현재 유저 모델에 대해 처음 생성이 되었을 때 user = kwargs['instance'] Profile.objects.create(user=user) # connect(호출될 함수, 어떠한 모델 객체가 저장되고 나서) post_save.connect(on_post_save_for_user, sender=settings.AUTH_USER_MODEL)
super(ProductInOrder, self).save(*args, **kwargs) def product_in_order_post_save(sender, instance, created, **kwargs): order = instance.order all_products_in_order = ProductInOrder.objects.filter(order=order, is_active=True) order_total_price = 0 for item in all_products_in_order: order_total_price += item.total_price instance.order.total_price = order_total_price instance.order.save(force_update=True) post_save.connect(product_in_order_post_save, sender=ProductInOrder) class ProductInCart(models.Model): session_key = models.CharField(max_length=128, blank=True, null=True, default=None) order = models.ForeignKey(Order, blank=True, null=True, default=None, verbose_name='Заказ') product = models.ForeignKey(Product, blank=True, null=True, default=None, verbose_name='Товар') quantity = models.PositiveIntegerField(default=1, verbose_name='Колличество') price_per_item = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='Цена') total_price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name='Итоговая стоимость') is_active = models.BooleanField(default=True, verbose_name='Активирован/Деактивирован') created = models.DateTimeField(auto_now_add=True, auto_now=False, verbose_name='Создан') updated = models.DateTimeField(auto_now_add=False, auto_now=True, verbose_name='Обновлён') def __str__(self):
def __str__(self): return str(self.following.all().count()) def get_following(self): users = self.following.all() return users.exclude(username=self.user.username).order_by("?")[:5] def get_following_count(self): users = self.following.all() return users.exclude(username=self.user.username) def get_tweets_count(self): return Tweet.objects.filter(user__username=self.user.username).count() def get_follow_url(self): return reverse_lazy("profiles:follow", kwargs={"username":self.user.username}) def get_absolute_url(self): return reverse_lazy("profiles:detail", kwargs={"username":self.user.username}) def post_save_user_recevier(sender, instance, created, *args, **kwargs): if created: new_profile = UserProfile.objects.get_or_create(user=instance) # print(instance) post_save.connect(post_save_user_recevier, sender=settings.AUTH_USER_MODEL)
chunks_content = {} if not chunks_content: chunks = InlineChunk.objects.filter(content_type=model_type, \ object_id=object_id) # build all chunks for this particular object for ch in chunks: chunks_content[ch.key] = ch.build_content(\ request, context, obj=self) cache.set(cache_key, chunks_content, cache_timeout) return chunks_content # import and cache all available chunks builders for cb in CHUNK_BUILDERS_LIST: package = cb[:cb.index('.')] cls_name = cb[cb.rindex('.') + 1:] module_name = cb[len(package) + 1:-len(cls_name) - 1] mdl = import_module(module_name, package=package) cls = getattr(mdl, cls_name) CHUNK_BUILDERS.append(cls()) # add default builder to end of list of builders CHUNK_BUILDERS.append(ChunkBuilder()) # cleanup Chunk model cache post_save.connect(clear_plain_chunk_cache, sender=Chunk) pre_delete.connect(clear_plain_chunk_cache, sender=Chunk)
from django.db.models.signals import post_save, post_delete from .models import Student def add_student(sender, **kwargs): pass post_save.connect(add_student, sender=Student) post_delete.connect(add_student, sender=Student)
class Profile(models.Model): user = models.OneToOneField(Signup, on_delete=models.CASCADE) profile_pic = models.ImageField(upload_to='profile', default='pic.jpg') dob = models.DateField(default=date.today) choices = (('Male', 'Male'), ('Female', 'Female'), ('Other', 'Other')) gender = models.CharField(max_length=9, choices=choices) friends = models.ManyToManyField("Profile", blank=True) def make_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) post_save.connect(make_profile, sender=Signup) def update_address(sender, instance, created, **kwargs): if created: print(instance) Profile.objects.create(paddr=instance) Profile.objects.create(company=instance) post_save.connect(update_address, sender=Address) class FriendRequest(models.Model): to_user = models.ForeignKey(Signup, related_name="to_user",
return self.ended def post_save_session_receiver(sender, instance, created, *args, **kwargs): if created: qs = UserSession.objects.filter(user=instance.user, ended=False, active=False).exclude(id=instance.id) for i in qs: i.end_session() if not instance.active and not instance.ended: instance.end_session() if FORCE_SESSION_TO_ONE: post_save.connect(post_save_session_receiver, sender=UserSession) def post_save_user_changer_receiver(sender, instance, created, *args, **kwargs): if not created: if instance.is_active == False: qs = UserSession.objects.filter(user=instance.user, ended=False, active=False) for i in qs: i.end_session() if FORCE_INACTIVE_USER_ENDSESSION: post_save.connect(post_save_user_changer_receiver, sender=User)
.get(pk=instance.user.profile.pk) except ObjectDoesNotExist: pass else: profile.num_of_submissions -= instance.num_of_submissions if profile.num_of_submissions < 0: profile.num_of_submissions = 0 profile.save() post_delete.connect(update_profile_num_submissions, sender=XForm, dispatch_uid='update_profile_num_submissions') def set_object_permissions(sender, instance=None, created=False, **kwargs): if created: from onadata.libs.permissions import OwnerRole OwnerRole.add(instance.user, instance) if instance.created_by and instance.user != instance.created_by: OwnerRole.add(instance.created_by, instance) from onadata.libs.utils.project_utils import set_project_perms_to_xform set_project_perms_to_xform(instance, instance.project) post_save.connect(set_object_permissions, sender=XForm, dispatch_uid='xform_object_permissions')
from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save class LFGProfile(models.Model): # Profile info fields user = models.ForeignKey(User) postal_code = models.IntegerField(blank=True, null=True) def __str__(self): return self.user.username def __unicode(self): return self.__str__() def create_user_profile(sender, instance, created, **kwargs): if created: LFGProfile.objects.create(user=instance) post_save.connect(create_user_profile, sender=User)
def get_data_for_excel(self): for d in self.get_list_of_parsed_instances(): for key in d.keys(): e = self.get_element(key) self._expand_select_all_that_apply(d, key, e) self._expand_geocodes(d, key, e) yield d def _mark_start_time_boolean(self): starttime_substring = 'jr:preloadParams="start"' if self.xml.find(starttime_substring) != -1: self.has_start_time = True else: self.has_start_time = False def get_survey_elements_of_type(self, element_type): return [ e for e in self.get_survey_elements() if e.type == element_type ] def set_object_permissions(sender, instance=None, created=False, **kwargs): if created: for perm in get_perms_for_model(XForm): assign_perm(perm.codename, instance.user, instance) post_save.connect(set_object_permissions, sender=DataDictionary, dispatch_uid='xform_object_permissions')
project_id = filters.get('project_id') if not project_id: project_id = extra['project'] group_id = filters.get('group_id') if not group_id: group_id = filters['group'].id app.buffer.incr(GroupTagKey, { 'values_seen': 1, }, { 'project_id': project_id, 'group_id': group_id, 'key': filters['key'], }) # Anything that relies on default objects that may not exist with default # fields should be wrapped in handle_db_failure post_syncdb.connect( handle_db_failure(create_default_projects), dispatch_uid="create_default_project", weak=False, ) post_save.connect( handle_db_failure(create_keys_for_project), sender=Project, dispatch_uid="create_keys_for_project", weak=False, )
related_name='wallet_to') timestamp = models.DateTimeField(auto_now_add=True) def clean(self): if self.wallet_from.id == self.wallet_to.id: raise ValidationError('Can not transfer to yourself') if self.wallet_from.balance < self.amount: raise ValidationError('Not enough funds to transfer') def create_profile(sender, **kwargs): user = kwargs["instance"] if kwargs["created"]: wallet = Wallet(user=user, balance=Decimal('100.0')) wallet.save() post_save.connect(create_profile, sender='auth.User') def transfer_sync(sender, **kwargs): transfer = kwargs['instance'] if kwargs['created']: transfer.wallet_to.balance = transfer.wallet_to.balance + transfer.amount transfer.wallet_from.balance = transfer.wallet_from.balance - transfer.amount transfer.wallet_to.save() transfer.wallet_from.save() post_save.connect(transfer_sync, sender='wallet.Transfer')
max_length=17, blank=True) # validators should be a list def __str__(self): return str(self.user) # reciver signal def profile_created(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) print('profile created') # signal connecting the receiver and user post_save.connect(profile_created, sender=User) # category class contains only name of categoris and relation with product class class Category(models.Model): title = models.CharField(max_length=35) cat_image = models.ImageField(null=True, blank=True) rate = models.FloatField(null=True) def __str__(self): return self.title # product class relation with category class Product(models.Model): category = models.ForeignKey(Category, on_delete=models.CASCADE)
def cart_item_pre_save_receiver(sender, instance, *args, **kwargs): qty = instance.quantity if qty >= 1: price = instance.item.get_price() line_item_total = Decimal(qty) * Decimal(price) instance.line_item_total = line_item_total pre_save.connect(cart_item_pre_save_receiver, sender=CartItem) def cart_item_post_save_receiver(sender, instance, *args, **kwargs): instance.cart.update_subtotal() post_save.connect(cart_item_post_save_receiver, sender=CartItem) post_delete.connect(cart_item_post_save_receiver, sender=CartItem) class Cart(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True) items = models.ManyToManyField(Variation, through=CartItem) timestamp = models.DateTimeField(auto_now_add=True, auto_now=False) updated = models.DateTimeField(auto_now_add=False, auto_now=True) subtotal = models.DecimalField(max_digits=50, decimal_places=2, default=25.00) tax_percentage = models.DecimalField(max_digits=10, decimal_places=5, default=0.085) tax_total = models.DecimalField(max_digits=50, decimal_places=2, default=25.00) total = models.DecimalField(max_digits=50, decimal_places=2, default=25.00) # discounts # shipping
instance.order_id = unique_order_id_generator(instance) qs = Order.objects.filter(cart=instance.cart).exclude( billing_profile=instance.billing_profile) if qs.exists(): qs.update(active=False) pre_save.connect(pre_save_create_order_id, sender=Order) def post_save_cart_total(sender, instance, created, *args, **kwargs): if not created: cart_obj = instance cart_total = cart_obj.total cart_id = cart_obj.id qs = Order.objects.filter(cart__id=cart_id) if qs.exists() and qs.count() == 1: order_obj = qs.first() order_obj.update_total() post_save.connect(post_save_cart_total, sender=Cart) def post_save_order(sender, instance, created, *args, **kwargs): if created: instance.update_total() post_save.connect(post_save_order, sender=Order)
@classmethod def site_created_hook(cls, sender, instance, raw, created, *args, **kwargs): """Creates canonical Alias object for a new Site.""" if raw or not created: return # When running create_default_site() because of post_syncdb, # don't try to sync before the db_table has been created. using = router.db_for_write(cls) tables = connections[using].introspection.table_names() if cls._meta.db_table not in tables: return # Update Alias.domain to match site cls.sync(site=instance) @classmethod def db_table_created_hook(cls, *args, **kwargs): """Syncs canonical Alias objects for all existing Site objects.""" Alias.canonical.sync_all() # Hooks to handle Site objects being created or changed pre_save.connect(Alias.site_domain_changed_hook, sender=Site) post_save.connect(Alias.site_created_hook, sender=Site) # Hook to handle syncdb creating the Alias table post_migrate.connect(Alias.db_table_created_hook)
related_modal_rounded_corners = models.BooleanField( default=True, verbose_name=_('rounded corners')) related_modal_close_button_visible = models.BooleanField( default=True, verbose_name=_('close button visible')) list_filter_dropdown = models.BooleanField(default=True, verbose_name=_('use dropdown')) list_filter_sticky = models.BooleanField(default=True, verbose_name=_('sticky position')) recent_actions_visible = models.BooleanField(default=True, verbose_name=_('visible')) def set_active(self): self.active = True self.save() class Meta: app_label = 'admin_interface' verbose_name = _('Theme') verbose_name_plural = _('Themes') def __str__(self): return force_str(self.name) post_delete.connect(Theme.post_delete_handler, sender=Theme) post_save.connect(Theme.post_save_handler, sender=Theme) pre_save.connect(Theme.pre_save_handler, sender=Theme)
updated_at = models.DateTimeField(auto_now=True) # automatically generated def __init__(self, *args, **kwargs): super(PurchasedOrder, self).__init__(*args, **kwargs) self.original_quantity = self.quantity def save(self, *args, **kwargs): # Only run when purchased order is being updated if self.pk: PurchasedOrderLogic.run_validations(self, self.original_quantity) super(PurchasedOrder, self).save(*args, **kwargs), self.id self.original_quantity = self.quantity def delete(self, *args, **kwargs): PurchasedOrderLogic.run_validations(self, self.original_quantity) super(PurchasedOrder, self).delete(*args, **kwargs) def __str__(self): return "Product: {} ({}) - Quantity Purchased: {}".format( self.product.name, self.product.id, self.quantity) pre_save.connect(PurchasedOrderSignals.update_in_stock_value, sender=PurchasedOrder) post_save.connect(PurchasedOrderSignals.create_or_update_order_stock, sender=PurchasedOrder) post_delete.connect(PurchasedOrderSignals.deletes_order_stock, sender=PurchasedOrder)