10

我使用名为UserExtension. 它通过唯一的 ForeignKey 关系与 User 相关联,这使我能够在管理员中以内联形式对其进行编辑!我正在使用信号为每个新用户创建一个新的配置文件:

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) 

(如这里所述,例如:Extended the User model with custom fields in Django)问题是,如果我通过管理员创建一个新用户,我会在保存“列 user_id 不是唯一的”时收到一个 IntegritiyError。信号似乎没有被调用两次,但我猜管理员正试图在之后保存配置文件?但是如果我在系统的其他部分创建一个新用户,我需要通过信号创建!

4

1 回答 1

15

django 之后会创建 admin 实例是正常的,因为保存的内容总是如下所示:

  1. 创建用户对象
  2. 创建 Profile 对象(不能在之前,因为它指向用户)。

保存用户对象时,django ORM 无法知道创建配置文件对象将在它之后出现,因此它不会以任何方式延迟 post_save 信号(甚至没有意义)。

如果您想保留 post_save 信号,处理此问题的最佳方法(恕我直言)是将 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)

请注意,这确实会强制每个指向与现有对象相同的用户的插入成为更新,这可能是其他代码部分的意外行为。

于 2010-05-11T19:13:08.190 回答