Как мне предотвратить фиксацию конфликтуют с сигнальным кодом django post_save?

В моем приложении я хочу создавать записи в определенных таблицах, когда новый пользователь регистрируется.Например, я хочу создать профиль пользователя, который затем будет ссылаться на их компанию и некоторые другие записи для них. Я реализовал это с помощью сигнала 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 при запуске приборов? Могу ли я определить, что я работаю как часть набора тестов, и не создаю эти записи? Следует ли мне сейчас удалить эти записи из приборов (хотя сигнал устанавливает только значения по умолчанию, а не значения, которые я хочу проверять)? Почему код загрузки фикстуры просто не перезаписывает созданные записи?

Как люди это делают?

47
задан Serjik 19 December 2015 в 08:58
поделиться

2 ответа

Думаю, я придумал, как это сделать. В 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

70
ответ дан 26 November 2019 в 19:33
поделиться

Я столкнулся с подобной проблемой в одном из моих проектов. В моем случае сигналы тоже тормозили тесты. В итоге я отказался от сигналов в пользу замены метода Model.save () .

Однако в вашем случае я не думаю, что имеет смысл достигать этого путем переопределения любых методов save () . В таком случае вы можете попробовать это. Предупреждение, я пробовал только один раз. Он казался работающим, но не был тщательно протестирован.

  1. Создайте свою собственную программу запуска тестов .
  2. Перед загрузкой приборов отключите функцию callback_create_profile от сигнала User класса post_save .
  3. Дайте приспособлениям загрузиться.
  4. Подключите функцию обратно к сигналу.
1
ответ дан 26 November 2019 в 19:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: