【问题标题】:Profile Creation Error: duplicate key value...user_id already exists配置文件创建错误:重复键值...user_id 已存在
【发布时间】:2012-06-15 11:40:35
【问题描述】:

我正在创建一个包含两种用户配置文件(DoctorProfile 和 PatientProfile)的站点。每个扩展 UserProfile,与 User 有 OneToOneField 关系。

尝试通过 ModelForm 注册新用户时,遇到以下错误:

duplicate key value violates unique constraint "accounts_userprofile_user_id_key"
DETAIL:  Key (user_id)=(38) already exists.

这似乎是在创建 PatientProfile 时发生的,它会尝试创建用户。但是,用户已经使用User.objects.create_user()创建了

如何配置它以便我只能创建一次用户?

这是我的(精简版)forms.py:

class PatientProfileForm(ModelForm):
    supplied_email = forms.CharField(max_length=256, label="Email Address", required=True)
    supplied_password = forms.CharField(max_length=256, label="Password", required=True, widget=forms.PasswordInput())
    supplied_password_confirm = forms.CharField(max_length=256, label="Password (again)", required=True, widget=forms.PasswordInput())

    def save(self, profile_callback=None):
        master_patient_profile = MasterPatientProfile(user=User.objects.create_user(username=self.cleaned_data['supplied_email'], email=self.cleaned_data['supplied_email'], password=self.cleaned_data['supplied_password']))
        master_patient_profile.save()

models.py 的简化版本:

class UserProfile(models.Model):
    user = models.OneToOneField(User, null=True)
    address_line_1 = models.CharField(_('Address 1'), max_length=100)
    address_line_2 = models.CharField(_('Address 2'), max_length=100, blank=True)
    city = models.CharField(_('City'), max_length=50)
    state = models.CharField(_('State'), max_length=20)
    zipcode = models.CharField(_('ZIP Code'), max_length=5)

class PatientProfile(UserProfile):
    gender = models.ForeignKey(UserGender)
    phone_number = models.CharField(max_length=12)
    date_of_birth = models.DateField(null=True)

class DoctorProfile(UserProfile):
    specialty = models.ManyToManyField(DoctorSpecialty)
    professional_statement = models.TextField()

编辑:(基于 Chris Pratt 的建议)

表单的save() 方法现在如下所示:

new_user, created = User.objects.get_or_create(username=self.cleaned_data['supplied_email'], email=self.cleaned_data['supplied_email'])
    if created:
        new_user.set_password(self.cleaned_data['supplied_password'])

    master_patient_profile = MasterPatientProfile(user=new_user)

【问题讨论】:

    标签: django django-authentication django-forms


    【解决方案1】:

    不要使用create_user。这纯粹是一种方便的方法,只对实际的User 创建表单真正有用。

    在其他任何地方,您都应该使用get_or_create。唯一的缺点是不能用那个设置密码,所以需要分两步完成。

    user, created = User.objects.get_or_create(username=self.cleaned_data['supplied_email'], email=self.cleaned_data['supplied_email'])
    if created:
        user.set_password(self.cleaned_data['supplied_password'])
    

    【讨论】:

    • 感谢您的提示。我已经合并了它。但是,由于用户仍由get_or_create() 创建,并且配置文件似乎仍在尝试创建用户,因此我仍然收到重复键错误。你知道避免这种情况的方法吗?
    • 如果提供的值 usernameemail 与数据库中的任何内容都不匹配,则用户只能由 get_or_create 创建。我认为你的问题在其他地方。您有任何与User 或您的任何模型相关的信号吗?
    • 这是一个新用户注册表单,所以我希望usernameemail 不匹配任何内容并创建一个新用户。您对信号的看法是正确的:我在 models.py 中有 post_save.connect(create_user_profile, sender=User),而 create_user_profile 正在创建第二个实例。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2019-06-22
    • 1970-01-01
    相关资源
    最近更新 更多