Opened 8 years ago

Closed 8 years ago

Last modified 5 years ago

#7648 closed (invalid)

Signal being throw too many times...

Reported by: italomaia Owned by: nobody
Component: Uncategorized Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


I tried to use the syncdb signal and noticed that, even being connected once, it was thrown more then once during the database sync. Shouldn't it
happen just once?

Change History (4)

comment:1 Changed 8 years ago by Russell Keith-Magee

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Resolution: invalid
Status: newclosed

The signal will only be emitted once. It's more than likely you have multiple registrations of a single listener on the signal. However, without detailed instructions on how to reproduce your problem, it's impossible to tell for certain. Marking invalid in the absence of sufficient detail to triage.

comment:2 Changed 8 years ago by italomaia

Resolution: invalid
Status: closedreopened

Fair enough. To reproduce this behavior, do as follow: startproject bad
cd bad
python startapp badsignal
configure your database
edit urls to

from django.conf.urls.defaults import *

# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    (r'^bad/', 'bad.badsignal.views.index'),

go to badsignal and edit to

# Create your views here.
from django.http import HttpResponse

from badsignal.models import Test

def index(request):
    return HttpResponse("Signal test.", mimetype="text/plain")

change models to

from django.db import models
from django.core.urlresolvers import reverse
from django.db.models import signals
from django.dispatch import dispatcher

# Create your models here.

class Test(models.Model):
    counter = models.IntegerField(default=0, blank=True)

def test_pre_save(sender, instance, signal, *args, **kwargs):
    print "UPDATED TEST ", instance.counter

dispatcher.connect( test_pre_save, sender=Test, signal=signals.post_save )

The evil is done! start your development server and access
In your console, you should see:

UPDATED TEST 2 <== attention! Called twice!

comment:3 Changed 8 years ago by Russell Keith-Magee

Resolution: invalid
Status: reopenedclosed

This isn't enough detail to replicate the problem completely, but let me fill in the missing pieces. Your project refers to the application "bad" in three places:

  • In the view, importing
  • In the admin, importing
  • In the settings, in INSTALLED_APPS.

Between these three places, you are referring to the application in two different ways:

  • from bad.models import *)
  • from badproject.bad.models import *

This means you are importing the application twice, and as a result, the signal is registered twice. This is a quirk of python model importing, and there isn't much we can do to work around this. The only solutions are:

  • Be consistent in the use of imports (i.e., only ever import
  • Put your registration somewhere else that won't be imported twice.

comment:4 Changed 5 years ago by Jacob

milestone: 1.0 beta

Milestone 1.0 beta deleted

Note: See TracTickets for help on using tickets.
Back to Top