2016-07-02 22 views
1

我正在使用常規/訪客用戶的Checkout視圖工作,但很難找出完整性錯誤。想法是讓客人用電子郵件只註冊結帳,我需要設置唯一的用戶電子郵件。Django IntegrityError電子郵件不是唯一的

models.py

from django.conf import settings 
from django.db import models 

class UserCheckout(models.Model): 
    user = models.OneToOneField(settings.AUTH_USER_MODEL, null=True, blank=True) 
    email = models.EmailField(unique=True) 

    def __unicode__(self): 
     return self.email 

forms.py

from django import forms 
from django.contrib.auth import get_user_model 

User=get_user_model() 
class GuestCheckoutForm(forms.Form): 
    email = forms.EmailField() 
    email2 = forms.EmailField(label='Verify Email') 
    def clean_email2(self): 
     email = self.cleaned_data.get("email") 
     email2 = self.cleaned_data.get("email2") 
     if email == email2: 
      user_exists = User.objects.filter(email=email).count() 
      if user_exists != 0: 
       raise forms.ValidationError("User already exists. Please login instead") 
      return email2 
     else: 
      raise forms.ValidationError("Please confirm emails addresses are the same.") 

在我車的意見,這是我是如何呈現自己的狀態。

def post(self, request, *args, **kwargs): 
     self.object = self.get_object() 
     form = self.get_form() 
     if form.is_valid(): 
      email = form.cleaned_data.get("email") 
      user_checkout = UserCheckout.objects.create(email=email) 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(form) 

我所註冊的模型管理員和管理員它顯示覆制完全正常,但是從前端我得到以下錯誤的錯誤:

IntegrityError at /checkout/ 
column email is not unique 
Request Method: POST 
Request URL: http://localhost:8000/checkout/ 
Django Version: 1.8.13 
Exception Type: IntegrityError 
Exception Value:  
column email is not unique 
Exception Location: C:\Users\Ali\ecomm\lib\site-packages\django\db\backends\sqlite3\base.py in execute, line 318 
Python Executable: C:\Users\Ali\ecomm\Scripts\python.EXE 
Python Version: 2.7.9 
+0

如果我理解正確,那麼表單在它不應該有效時會有效,並且會導致「IntegrityError」錯誤? – aumo

+0

我打算做的只是如果用戶已經存在,它應該彈出消息登錄而不是註冊。 –

回答

2

您創建每次結帳時發生一個新的UserCheckout。在所有這些條目中,只允許每個電子郵件只存在一次。

我不認爲你想要這個。因爲如果客人訂購兩次,則不允許,因爲他的電子郵件已經在數據庫中。這就是你得到這個錯誤的原因。

1

一個Formclean_<fieldname>方法用於相對於單個字段執行驗證。如果您需要驗證訪問多個字段,請使用clean方法。請在表單驗證上檢查documentation以獲取詳細解釋。

這將使:

class GuestCheckoutForm(forms.Form): 
    email = forms.EmailField() 
    email2 = forms.EmailField(label='Verify Email') 

    def clean_email(self): 
     email = self.cleaned_data["email"] 
     if User.objects.filter(email=email).exists(): 
      raise forms.ValidationError("Please confirm emails addresses are the same.") 
     return email 

    def clean(self): 
     cleaned_data = super(GuestCheckoutForm, self).clean() 
     email = cleaned_data.get('email') 
     email2 = cleaned_data.get('email2') 

     if email and email2 and email != email2: 
      self.add_error('email2', forms.ValidationError('Please confirm emails addresses are the same.')) 

編輯:我相信我發現了,爲什麼你得到了一個IntegrityError: 你是驗證沒有User特定電子郵件是在數據庫中,你也應該驗證數據庫中沒有其他UserCheckout與給定的電子郵件。替換if User.objects.filter(email=email).exists():通過if User.objects.filter(email=email).exists() or UserCheckout.objects.filter(email=email).exists():

+0

它不讓我在python 2.7中調用super()。其次在最後一行ValidationError不可解析。它顯示錯誤。 super()至少需要1個參數(給出0) –

+0

與發佈的問題相同的錯誤。沒有改變。但我明白你的觀點。但是,這給了我一個想法,只要邏輯清晰,就可以捕捉並更改完整性錯誤。你認爲這是一個更好的主意嗎? –

+0

我認爲這是一個解決方案,但是一個醜陋的解決方案,你顯然有一個地方,你會藏起來,這可能會咬你以後。 P.-S.你見過我的編輯嗎? – aumo