【发布时间】: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