代码之家  ›  专栏  ›  技术社区  ›  Bernhard Vallant

django:django admin中具有唯一外键的用户配置文件

  •  10
  • Bernhard Vallant  · 技术社区  · 14 年前

    我使用一个名为 UserExtension . 它通过一个独特的foreignkey关系与用户相关,这使我能够以内联形式在admin中编辑它! 我正在使用一个信号为每个新用户创建一个新的配置文件:

    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) 
    

    (如本文所述,例如: Extending the User model with custom fields in Django ) 问题是,如果我通过admin创建一个新用户,那么保存“column user_id is not unique”时会得到一个整合器错误。似乎没有两次调用该信号,但我想管理员稍后会试图保存配置文件吗? 但是如果我在系统的其他部分创建一个新用户,我需要通过信号来创建!

    1 回复  |  直到 14 年前
        1
  •  15
  •   Jonatan Littke Yukiup    12 年前

    Django随后将创建管理实例是正常的,因为保存总是由以下内容组成:

    1. 创建用户对象
    2. 创建配置文件对象(之前不能,因为它指向用户)。

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

    如果要保留post-save信号,处理此(imho)的最佳方法是重写 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)
    

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