Я создал модель профиля (с отношением 1 к 1 с моделью пользователя), как описано в Расширение существующей модели пользователя. Модель профиля имеет необязательное отношение "много-к-одному" к другой модели:
class Profile(models.Model):
user = models.OneToOneField(User, primary_key=True)
account = models.ForeignKey(Account, blank=True, null=True, on_delete=models.SET_NULL)
Как описано там, я также создал встроенный администратор:
class ProfileInline(admin.StackedInline):
model = Profile
can_delete = False
verbose_name_plural = 'profiles'
# UserAdmin and unregister()/register() calls omitted, they are straight copies from the Django docs
Теперь, если я не выбираю account
в admin при создании пользователя, модель профиля не будет создана. Поэтому я connect в сигнал post_save, снова просто следуя документации:
@receiver(post_save, sender=User)
def create_profile_for_new_user(sender, created, instance, **kwargs):
if created:
profile = Profile(user=instance)
profile.save()
Это работает отлично, пока я не выбираю account
в admin, но если да, я получу исключение IntegrityError
, сообщая мне, что duplicate key value violates unique constraint "app_profile_user_id_key" DETAIL: Key (user_id)=(15) already exists.
По-видимому, встроенный администратор пытается создать сам экземпляр profile
, но мой обработчик сигнала post_save
уже создал его в это время.
Как исправить эту проблему, соблюдая все следующие требования?
- Независимо от того, как создается новый пользователь, с ним всегда будет ссылка
profile
. - Если пользователь выбирает
account
в админе во время создания пользователя, этотaccount
будет установлен в новой моделиprofile
. Если нет, полеnull.
Среда: Django 1.5, Python 2.7
Похожие вопросы:
- Создание расширенного профиля пользователя (похожие симптомы, но причина оказалась другой)