【问题标题】:Django: UserProfile with Unique Foreign Key in Django AdminDjango:在 Django Admin 中具有唯一外键的 UserProfile
【发布时间】:2010-05-11 18:00:59
【问题描述】:

我使用名为UserExtension 的自定义用户配置文件扩展了 Django 的用户模型。 它通过唯一的 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) 

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

【问题讨论】:

  • 我们可以见您的 get_or_create 经理吗?
  • 是django的默认管理器!

标签: django inline admin django-signals foreign-keys


【解决方案1】:

django 之后会创建管理实例是正常的,因为保存总是包含这样的内容:

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

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

如果您想保留 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)

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

【讨论】:

  • 覆盖模型的默认保存方法对我来说似乎是一个好而简单的想法,必须检查它是否适用于所有用例!我认为“existing = UserExtension.objects.all().get(user=self.user)”可以是“existing = UserExtension.objects.get(user=self.user)”,或者你有什么特别的想法吗?那? :) 谢谢!
  • 没什么特别的,据我所知你不需要.all()。我不知道我为什么添加它
猜你喜欢
  • 2011-05-30
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-16
  • 2012-09-16
  • 2021-06-13
  • 1970-01-01
相关资源
最近更新 更多