#7648 closed (invalid)
Signal being throw too many times...
Reported by: | italomaia | Owned by: | nobody |
---|---|---|---|
Component: | Uncategorized | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 16 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Fair enough. To reproduce this behavior, do as follow:
django-admin.py startproject bad
cd bad
python manage.py 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 views.py to
# Create your views here. from django.http import HttpResponse from badsignal.models import Test def index(request): Test.objects.create() 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): instance.counter+=1 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
http://localhost:8000/bad/
In your console, you should see:
UPDATED TEST 1
UPDATED TEST 2 <== attention! Called twice!
COUNTER 1
comment:3 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | reopened → closed |
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 models.py
- In the admin, importing models.py
- 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 bad.models.py)
- Put your registration somewhere else that won't be imported twice.
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.