Django:Django 管理中具有唯一外键的用户配置文件

标签 django inline admin django-signals foreign-keys

我使用名为 UserExtension 的自定义用户配置文件扩展了 Django 的用户模型。 它通过独特的外键关系与用户相关,这使我能够以内联形式在管理中编辑它! 我正在使用信号为每个新用户创建新的个人资料:

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 。信号似乎没有被调用两次,但我猜管理员正在尝试事后保存配置文件? 但是如果我在系统的其他部分创建新用户,我需要通过信号创建!

最佳答案

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

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

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

如果您想保留 post_save 信号,处理此问题的最佳方法(恕我直言)是将 UserExtension 的 save 方法重写为如下所示:

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)

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

关于Django:Django 管理中具有唯一外键的用户配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2813189/

相关文章:

cmd - NSIS - 当 RequestExecutionLevel admin 不够用时,如何将 admin 级别继承给 ExecShell?

python - 具有基于文件的电子邮件后端服务器的 Django 测试框架

javascript - 如何在 Django 模板中执行此操作

python - Django vs Python2.7 单元测试测试用例?

css - 如何在section标签中设置相同图片的不同背景图片格式(png和webp)

google-app-engine - App Engine 管理 API 错误 - 需要 "appengine.applications.create"权限

找不到 Django 管理页面

python - 在 Django 中合并查询集

html - 如何防止内联列表元素的两侧在 HTML 中被截断?

javascript - 三元表达式 JavaScript 中的三元表达式