简体   繁体   English

Django 完整性错误 - 唯一约束失败

[英]Django Integrity Error- Unique Constraint Failed

Trying to create a simple launch page for my website to collect email addresses.尝试为我的网站创建一个简单的启动页面来收集电子邮件地址。 When the user goes to submit, it is providing the following error (traceback below)--Unique Constraint Failed---accounts.user.username.当用户提交时,它提供以下错误(以下回溯)--Unique Constraint Failed ---accounts.user.username。 I figured maybe this has to do with the email address entered overlapping with username, but as you can see in my accounts model--the username is created from the email.我想这可能与输入的电子邮件地址与用户名重叠有关,但正如您在我的帐户模型中看到的那样——用户名是从电子邮件中创建的。 (Note the entire User and User Profile models are not being utilized throughout my site yet, but just preparing for future usage). (注意整个用户和用户配置文件模型还没有在我的网站上使用,只是为将来的使用做准备)。 Any help is appreciated.任何帮助表示赞赏。 Thanks谢谢

Traceback (most recent call last):
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\crstu\PycharmProjects\dealmazing\dealmazing\views.py", line 15, in newsletter_signup
    instance.save()
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\contrib\auth\base_user.py", line 74, in save
    super(AbstractBaseUser, self).save(*args, **kwargs)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 708, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 736, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 820, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\base.py", line 859, in _do_insert
    using=using, raw=raw)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\manager.py", line 122, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py", line 1039, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\sql\compiler.py", line 1060, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\backends\sqlite3\base.py", line 323, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: accounts_user.username

my Accounts app model below:我的帐户应用程序模型如下:

from django.contrib.auth.models import (
    AbstractBaseUser,
    BaseUserManager,
    PermissionsMixin
)
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.db.models.signals import post_save
import os


def avatar_upload_path(instance, filename):
    return os.path.join('avatars', 'user_{0}', '{1}').format(
        instance.user.id, filename)


class UserManager(BaseUserManager):
    def create_user(self, email, username=None, password=None):
        if not email:
            raise ValueError("Users must have an email address")

        if not username:
            username = email.split('@')[0]

        user = self.model(
            email=self.normalize_email(email),
            username=username,
        )
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, username, password):
        user = self.create_user(
            email,
            username,
            password,
        )
        user.is_staff = True
        user.is_superuser = True
        user.save()
        return user


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=40, unique=True, default='')
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def __str__(self):
        return "@{}".format(self.username)

    def get_short_name(self):
        return self.username

    def get_long_name(self):
        return "@{} ({})".format(self.username, self.email)


class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, primary_key=True, related_name='profile')
    first_name = models.CharField(max_length=40, default='', blank=True)
    last_name = models.CharField(max_length=40, default='', blank=True)
    bio = models.TextField(blank=True, default='')
    avatar = models.ImageField('Avatar picture',
                               upload_to=avatar_upload_path,
                               null=True,
                               blank=True)

    def __str__(self):
        return self.user.username

    @property
    def get_avatar_url(self):
        if self.avatar:
            return '/media/{}'.format(self.avatar)
        return 'http://www.gravatar.com/avatar/{}?s=128&d=identicon'.format(
            '94d093eda664addd6e450d7e9881bcad'
        )


def create_profile(sender, **kwargs):
    if kwargs['created']:
        user_profile = UserProfile.objects.create(user=kwargs['instance'])

post_save.connect(create_profile, sender=User)

and here's the view for my actual newsletter that is collecting email address.这是我收集电子邮件地址的实际时事通讯的视图。 note i'm just temporarily redirecting to google for now as a test:请注意,我只是暂时重定向到谷歌作为测试:

from django.shortcuts import render, redirect
from newsletters.forms import NewsletterUserSignUpForm
from accounts.models import User


def newsletter_signup(request):
    if request.method == "POST":
        form = NewsletterUserSignUpForm(request.POST)

        if form.is_valid():
            instance = form.save(commit=False)
            if User.objects.filter(email=instance.email).exists():
                print("Sorry this email already exists")
            else:
                instance.save()
                return redirect("http://www.google.com")

    else:
        form = NewsletterUserSignUpForm()

    template = "newsletters/sign_up.html"
    return render(request, template, {'form': form})

sign up html form looks like this:注册 html 表单如下所示:

  <div class="col-lg-6 offset-lg-3">
      <form method="POST">
        {% csrf_token %}
         <div class="form-group">
           <div class="col-xs-6 col-xs-offset-3">
          {{ form.email}}
        <button class="btn btn-primary" type="submit">Sign Up!</button>
           </div>
         </div>
      </form>
        </div>
    </div>

Your User model has a username field which requires unique=True which is the cause of your problem.您的User模型有一个 username 字段,它需要unique=True这是导致问题的原因。 Now you might be having a user having a username field as '' which is default.现在您可能有一个用户名字段为''的用户,这是默认值。 Since you already have one user with this username you can't have another user with this field.由于您已经有一个使用此用户名的用户,因此您不能再有其他用户使用此字段。 You should check that user already exists in the db or not also you have to enter some username with a user don't use default with unique=True its a really bad design and always fails.您应该检查用户是否已经存在于数据库中,您还必须输入一些用户名,用户不要使用 unique=True 的默认值,这是一个非常糟糕的设计并且总是失败。

since you are using username = email.split('@')[0] to get the username for the user.因为您使用username = email.split('@')[0]来获取用户的用户名。 It is possible that two different email would give you same value for the username .两个不同的电子邮件可能会给您提供相同的username值。 For example example@abc.com and example@def.com .例如example@abc.comexample@def.com What you need to do is figure out some other algorithm to set the username or a good idea can be to user the email as username.您需要做的是找出一些其他算法来设置username或者一个好主意可以是将email用作用户名。

在您的帐户应用程序模型中尝试这个user.save(using=self._db) ,这可能对您有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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