Джанго сигналы.Как создать уникальный идентификатор отправки? - PullRequest
2 голосов
/ 22 марта 2012

иногда сигналы в джанго запускаются дважды. В документации сказано, что хорошим способом создания (уникального) dispatch_uid является либо путь или имя модуля [1], либо идентификатор любого объекта, который может быть изменен [2].

Сегодня я попробовал это:

import time
my_signal.connect(my_function, dispatch_uid=str(time.time()))

Однако я боюсь, что в многопользовательской среде (как в случае с веб-сайтом). Это может быть сломано. Что такое хороший и безопасный способ создания такого идентификатора в многопользовательской среде?

[1] https://code.djangoproject.com/wiki/Signals

[2] https://docs.djangoproject.com/en/dev/topics/signals/#preventing-duplicate-signals

Ответы [ 2 ]

11 голосов
/ 22 марта 2012

Использование времени в качестве идентификатора отправки не будет работать. Вопрос не в том, является ли ваша среда многопользовательской или нет. Будет ли код, который связывает сигналы, импортирован более одного раза.

Скажем, ваш модуль был импортирован дважды с интервалом в 5 секунд. Вы фактически сделали следующее.

my_signal.connect(my_function, dispatch_uid=1332407342.51)
my_signal.connect(my_function, dispatch_uid=1332407352.51)

Ваш сигнал был связан дважды с разными идентификаторами отправки. Эта структура проекта по умолчанию для Django 1.3 и более ранних версий позволяет осуществлять двойной импорт, поскольку модули часто можно импортировать как project.my_app.module и my_app.module.

Если вы выберете соглашение, подобное my_app.models.function_name, как предлагает Дмитрий, то при втором импорте модуля сигнал не будет подключен дважды, поскольку идентификатор отправки не изменился. Вы не должны повторно использовать один и тот же идентификатор отправки для регистрации различных функций обратного вызова с одним и тем же сигналом.

7 голосов
/ 22 марта 2012

Просто используйте строку для модуля, как 'apps.models.signal_name'

...