Django: UserProfile с уникальным внешним ключом в администраторе Django

Я расширил Пользовательскую Модель Django использование пользовательского названного профиля пользователя UserExtension. Это связано с Пользователем через уникальные Отношения ForeignKey, которые позволяют мне отредактировать его в администраторе во встроенной форме! Я использую сигнал создать новый профиль для каждого нового пользователя:

def create_user_profile(sender, instance, created, **kwargs):  
    if created:
        try:  
            profile, created = UserExtension.objects.get_or_create(user=instance)
        except:
            pass  

post_save.connect(create_user_profile, sender=User) 

(как описано здесь, например: Расширение модели User с пользовательскими полями в Django) проблема, который, если я создаю нового пользователя через администратора, я получаю, IntegritiyError при сохранении "столбца user_id не уникален". Не кажется, что сигнал называют дважды, но я предполагаю, что администратор пытается сохранить профиль ВПОСЛЕДСТВИИ? Но мне нужно создание через сигнал, если я создаю нового пользователя в других частях системы!

10
задан Community 23 May 2017 в 11:56
поделиться

1 ответ

Это нормально, что django впоследствии создаст экземпляр администратора, так как сохранение всегда состоит из чего-то вроде этого:

  1. Создать объект пользователя
  2. Создать объект профиля (не может быть раньше, потому что он указывает на пользователя) .

При сохранении объекта User django ORM не может знать, что объект создания профиля появится после него, поэтому он никоим образом не задерживает сигнал post_save (даже не имеет смысла).

Лучший способ справиться с этим (imho), если вы хотите сохранить сигнал post_save, - это переопределить метод сохранения UserExtension примерно таким:

def save(self, *args, **kwargs):
    try:
        existing = UserExtension.objects.get(user=self.user)
        self.id = existing.id #force update instead of insert
    except UserExtension.DoesNotExist:
        pass 
    models.Model.save(self, *args, **kwargs)

Обратите внимание, что это заставляет каждую вставку который указывает на того же пользователя, что и существующий объект, чтобы стать обновлением, это может быть неожиданным поведением для других частей кода.

15
ответ дан 3 December 2019 в 22:35
поделиться
Другие вопросы по тегам:

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