我有一个标准UserProfile
模型,其OneToOneField
字段到auth.User
模型。
每个User
必须只有一个UserProfile
,因此我需要在创建UserProfile
时始终创建User
个对象。
显而易见的解决方案是创建一个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),此方法有效。
问题是通过user
创建django-admin
时。它提出了:
重复键值违反了唯一约束 “main_userprofile_user_id_key”DETAIL:Key(user_id)=(30)已经 存在。
我在UserProfile
管理页面中添加了User
内联,这意味着有两种形式 - 用于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']
现在,当管理员通过user
创建新django-admin
并填充至少一个UserProfile
表单字段时,django会尝试为{{1}创建UserProfile
两次返回错误。由user
创建后,第二次因为signal
表单填写了至少一个表单字段。
你知道怎么做吗?
修改
我会在UserProfile
:
signal
但是在保存管理员的if not getattr(instance,'userprofile'):
# create userprofile
modelform之前调用了信号,所以它无济于事。
答案 0 :(得分:0)
我设法将@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。