简体   繁体   中英

Django IntegrityError email is not unique

I am working on my Checkout view with regular/guest user but getting hard time to come around the integrity error. Idea is to let guest users register with email only to checkout and I need to set the user email unique.

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.")

In my cart views this is how I've rendered my form.

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)

I've registered the model with admin and in admin it shows the error for duplication perfectly fine but from frontend I am getting error below:

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

You create every time when a checkout occurs an new UserCheckout . And in all these entries it is only allowed that every email exists only once.

I don't think you want this. Because if a guest orders two times it isn't allowed because his email is already in the DB. And that's why you get this error.

The clean_<fieldname> methods of a Form are used to perform validation relative to single field. If you need validation with access to multiple fields, use the clean method. Check the documentation on form validation for a thorough explanation.

That would give:

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.'))

EDIT: I believe I found out why you got an IntegrityError : You are validation that no User with the given email is in the database, you should also be validating that no other UserCheckout with the given email is in the database. Replace if User.objects.filter(email=email).exists(): by if User.objects.filter(email=email).exists() or UserCheckout.objects.filter(email=email).exists():

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM