2012-06-12 68 views
-1

我正在創建一個包含兩種類型的用戶配置文件(DoctorProfile和PatientProfile)的站點。每個擴展UserProfile,它與User有一個OneToOneField關係。配置文件創建錯誤:重複鍵值... user_id已存在

雖然試圖通過向的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 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() 

編輯:(基於克里斯普拉特的建議)

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的縮短版

窗體的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) 

回答

2

請勿使用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']) 
+0

感謝您的提示。我已經合併了它。但是,由於用戶仍然由'get_or_create()'創建,並且該配置文件似乎仍然嘗試創建用戶,所以我仍然得到了重複鍵錯誤。你知道一種避免這種情況的方法嗎? –

+0

如果提供的值「username」和「email」與數據庫中的任何內容不匹配,用戶將僅通過'get_or_create'獲得創建。我認爲你的問題在別處。你有沒有任何信號與'User'或你的任何模型綁定在一起? –

+0

這是一個新的用戶註冊表單,所以我希望'username'和'email'不能匹配任何內容,並且要創建一個新用戶。 你說的很對:我在models.py中創建了'post_save.connect(create_user_profile,sender = User)','create_user_profile'創建了第二個實例。謝謝您的幫助! –