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

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

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

4 Solutions collect form web for “Как предотвратить конфликты приборов с конфликтом с сигнальным кодом django post_save?”

Думаю, я понял, как это сделать. В kwargs, переданном вместе с сигналами, есть «сырой» параметр, поэтому я могу заменить мой тест выше на этот:

 if (kwargs.get('created', True) and not kwargs.get('raw', False)): 

Необработанное используется при загрузке loaddata. Кажется, это трюк.

Он упоминается здесь: http://code.djangoproject.com/ticket/13299

Было бы неплохо, если бы это было задокументировано: http://docs.djangoproject.com/en/1.2/ref/signals/#django.db.models.signals.post_save

Это старый вопрос, но решение, которое я нашел наиболее простым, – использовать «исходный» аргумент, переданный данными загрузки, и украсить функции слушателя, например:

 from functools import wraps def disable_for_loaddata(signal_handler): @wraps(signal_handler) def wrapper(*args, **kwargs): if kwargs['raw']: print "Skipping signal for %s %s" % (args, kwargs) return signal_handler(*args, **kwargs) return wrapper 

а потом

 @disable_for_loaddata def callback_create_profile(sender, **kwargs): # check if we are creating a new User ... 

Простое решение, добавьте это в начало вашей функции post_save:

 if kwargs.get('raw', False): return False 

Это приведет к выходу этой функции при загрузке прибора.

См. https://docs.djangoproject.com/en/dev/ref/signals/#post-save

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

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

  1. Создайте свой собственный тестовый бегун .
  2. Прежде чем загружать светильники, отключите функцию callback_create_profile из сигнала post_save User класса.
  3. Пусть светильники загружаются.
  4. Подключите функцию к сигналу.
  • Как перебрать выбор полей формы и отобразить связанные с ними экземпляры экземпляра модели
  • Django: обратные аксессоры для внешних ключей
  • Межплатформенный интерфейс для virtualenv
  • Странное поведение для аннотата в Django
  • Запуск пауков Scrapy в задаче Сельдерея
  • Как получить доступ к именам пользователей и профилям с помощью django-allauth
  • Как получить уникальные электронные письма с помощью python social auth
  • Ошибка страницы администратора Django
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.