В моем приложении я хочу создавать записи в определенных таблицах, когда новый пользователь регистрируется.Например, я хочу создать профиль пользователя, который затем будет ссылаться на их компанию и некоторые другие записи для них. Я реализовал это с помощью сигнала post_save:
def callback_create_profile(sender, **kwargs):
# check if we are creating a new User
if kwargs.get('created', True):
user = kwargs.get('instance')
company = Company.objects.create(name="My Company")
employee = Employee.objects.create(company=company, name_first=user.first_name, name_last=user.last_name)
profile = UserProfile.objects.create(user=user, employee=employee, partner=partner)
# Register the callback
post_save.connect(callback_create_profile, sender=User, dispatch_uid="core.models")
Это хорошо работает при запуске. Я могу использовать администратора для создания нового пользователя, а остальные три таблицы также получают записи с разумным. (За исключением того, что это сотрудник, поскольку user.first_name и user.last_name не заполняются в форме администратора при сохранении. Я до сих пор не понимаю, почему это делается именно так)
Проблема возникла, когда я запустил свой набор тестов. Перед этим я создал несколько приспособлений для создания этих записей в таблицах. Теперь я получаю сообщение об ошибке:
IntegrityError: duplicate key value violates unique constraint "core_userprofile_user_id_key"
Я думаю, это связано с тем, что я уже создал записи о компании, сотрудниках и профиле в устройстве с идентификатором «1», и теперь сигнал post_save пытается их воссоздать.
Мои вопросы: могу ли я отключить этот сигнал post_save при запуске приборов? Могу ли я определить, что я работаю как часть набора тестов, и не создаю эти записи? Следует ли мне сейчас удалить эти записи из приборов (хотя сигнал устанавливает только значения по умолчанию, а не значения, которые я хочу проверять)? Почему код загрузки фикстуры просто не перезаписывает созданные записи?
Как люди это делают?
Думаю, я придумал, как это сделать. В kwargs, переданных вместе с сигналами, есть параметр 'raw', поэтому я могу заменить свой тест, приведенный выше, следующим:
if (kwargs.get('created', True) and not kwargs.get('raw', False)):
Raw используется при выполнении loaddata. Кажется, это помогает.
Это упомянуто здесь: http://code.djangoproject.com/ticket/13299
Было бы неплохо, если бы это было задокументировано: http://docs.djangoproject.com/en/ 1.2 / ref / signal / # django.db.models.signals.post_save
Я столкнулся с подобной проблемой в одном из моих проектов. В моем случае сигналы тоже тормозили тесты. В итоге я отказался от сигналов в пользу замены метода Model.save ()
.
Однако в вашем случае я не думаю, что имеет смысл достигать этого путем переопределения любых методов save ()
. В таком случае вы можете попробовать это. Предупреждение, я пробовал только один раз. Он казался работающим, но не был тщательно протестирован.
callback_create_profile
от сигнала User
класса post_save
.