【问题标题】:Django admin: Integrity error caused by signalDjango admin:由信号引起的完整性错误
【发布时间】:2018-11-24 08:40:12
【问题描述】:

我有一个标准的UserProfile 模型,它有一个OneToOneField 字段到auth.User 模型。

每个User 必须有一个且只有一个UserProfile,所以我需要在创建User 时始终创建UserProfile 对象。

显而易见的解决方案是创建一个post_save 信号:

@receiver(post_save,sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.get_or_create(user=instance)

问题:

user 注册自己或user 以编程方式创建时(例如通过shell),此方法有效。

问题是通过django-admin 创建user 时。它提出:

重复键值违反唯一约束 “main_userprofile_user_id_key”详细信息:密钥 (user_id)=(30) 已经 存在。

我在User 管理页面中添加了一个UserProfile 内联,这意味着有两种形式- 用于User 创建和UserProfile 创建。

admin.site.unregister(User)


class UserProfileInline(admin.StackedInline):
    model = UserProfile


class UserAdmin(BaseUserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        # (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    #
    ordering = ('username',)
    inlines = [UserProfileInline]
    list_display = ['id', 'username', 'userprofile__display_name','last_login']

现在,当管理员通过django-admin 创建一个新的user 并填写至少一个UserProfile 表单字段时,django 会尝试为user 创建一个UserProfile 两次,这会返回错误。一次是因为signal 而创建的,第二次是因为至少有一个UserProfile 表单的表单字段已填写。

你知道如何让它工作吗?

编辑

我会在signal 中添加一个条件:

if not getattr(instance,'userprofile'):
    # create userprofile

但是在保存来自管理员的UserProfile modelform 之前调用了该信号,因此它无济于事。

【问题讨论】:

  • 顺便说一句,您也可以不使用信号创建UserProfile - 您可以覆盖模型的save() 方法并在保存User 之前在那里创建它。
  • 如果你实现了内联,你是否尝试过覆盖save_related

标签: django database django-models django-admin


【解决方案1】:

我设法将@Chiefir 的建议实现为用户代理模型:

from django.contrib.auth.models import User

class UserProxy(User):
    class Meta:
        proxy = True

    def save(self):
        UserProfile.objects.get_or_create(user=self)
        super(UserProxy, self).save()

并注释掉信号线:

# signals.post_save.connect(create_profile, sender=User)

另请参阅:https://docs.djangoproject.com/en/3.2/topics/auth/customizing/https://docs.djangoproject.com/en/3.2/topics/db/models/#proxy-models

【讨论】:

    猜你喜欢
    • 2013-03-18
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多