Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#3495 closed (worksforme)

created_models doesn't match post_syncdb's app

Reported by: Yary H <spam-django@…> Owned by: adrian
Component: Core (Other) Version: master
Severity: Keywords:
Cc: not.com@… Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

When post_syncdb triggers a signal for one app, the "created_models" includes models created in other apps.

from django.dispatch import dispatcher
from django.db.models import signals

def show_it(sender, app, created_models, verbosity, interactive):
  print app, created_models
 
dispatcher.connect(show_it,signal=signals.post_syncdb)

Put that in the init.py in one app of a multi-app project and try running "manage.py test"- notice that for every app, show_it is called with "created_models" that don't necessarily match "app".

Change History (4)

comment:1 Changed 9 years ago by Michael Radziej <mir@…>

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

I think this is by design. The signal dispatcher does not care about applications. But this is necessary to implemenent certain types of cross-application behaviour (e.g., logging each object creation or modification).

But I pass it on for core to decide.

comment:2 Changed 9 years ago by yary h <spm-django@…>

Thanks, I suspect it's not the dispatcher but the signal issuer that's responsible for created_models. And the real issue for me isn't that there are non-app models listed, but that some models get listed repeatedly, as if they're created more than once.

I already have work-arounds, perhaps documenting the behavior is enough, "just thought you'd like to know."

comment:3 Changed 9 years ago by ubernostrum

  • Resolution set to worksforme
  • Status changed from new to closed

Actually, I think the issue here is that you're listening for every instance of the post_syncdb signal, when what you want is only instances of post_syncdb which apply to a single specific app. You can do that by adding the keyword argument sender to dispatcher.connect; for example, the auth app knows to fire off create_superuser by doing:

from django.contrib.auth import models as auth_app

# ...snip...

dispatcher.connect(create_superuser, sender=auth_app, signal=signals.post_syncdb)

created_models, IIRC, is a growing list of all models syncdb has installed so far, so you can check for specific models in the list if you're interested in them (and the auth app does this as well, by checking whether the user model is in created_models before trying to instantiate and save one).

comment:4 Changed 9 years ago by Yary H <spam-django@…>

No that's not the issue, I want to process all models, regardless of app at syncdb time, and I want to process each model only once. I've edited the wiki at http://code.djangoproject.com/wiki/Signals for clarity.

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