【问题标题】:Django Integrity Error- Unique Constraint FailedDjango 完整性错误 - 唯一约束失败
【发布时间】:2018-01-05 12:00:12
【问题描述】:

尝试为我的网站创建一个简单的启动页面以收集电子邮件地址。当用户提交时,它提供以下错误(下面的回溯)--唯一约束失败--accounts.user.username。我想这可能与输入的电子邮件地址与用户名重叠有关,但正如您在我的帐户模型中看到的那样——用户名是从电子邮件创建的。 (请注意,整个用户和用户配置文件模型尚未在我的整个站点中使用,只是为将来的使用做准备)。任何帮助表示赞赏。谢谢

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

我的帐户应用模型如下:

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)

这是我收集电子邮件地址的实际时事通讯的视图。请注意,我现在只是暂时重定向到谷歌作为测试:

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})

注册 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>

【问题讨论】:

    标签: python django


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      因为您使用username = email.split('@')[0] 来获取用户的用户名。两封不同的电子邮件可能会为您提供相同的 username 值。例如example@abc.comexample@def.com。您需要做的是找出一些其他算法来设置username,或者一个好主意可以使用email 作为用户名。

      【讨论】:

      • 我不认为这是问题所在——因为我已经用大量不同的电子邮件对其进行了多次测试,但仍然遇到同样的错误
      【解决方案3】:

      您的User 模型有一个用户名字段,该字段需要unique=True,这是您的问题的原因。现在您可能有一个用户的用户名字段为'',这是默认设置。由于您已经有一个具有此用户名的用户,因此您不能有另一个具有此字段的用户。您应该检查用户是否已经存在于数据库中,您还必须输入一些用户名,用户不要使用默认值,unique=True 这是一个非常糟糕的设计并且总是失败。

      【讨论】:

      • 好的,我认为您在这里肯定是正确的。数据库中已经有两个用户 - 一个具有用户名的超级用户另一个具有默认用户名的用户。当我使用空白用户名输入该用户的用户名时,该表单有效。因此,我删除了 default='' 但是当我在表单中输入新用户电子邮件时,问题不断出现。我需要在注册表单的视图中将用户名设置为电子邮件吗?
      • 您必须在表单中填写用户名字段并在保存之前检查用户是否存在。如果可能结果是用户名已经存在于 dB 中,也不要从电子邮件中创建用户名。从用户那里获取用户名并检查它是否存在,如果不存在则继续创建用户
      • 我唯一的问题是我只是想创建一个临时的时事通讯注册表单——唯一的输入是电子邮件,所以不收集用户的用户名。
      • 所以从你的用户模型中删除用户名字段。无论哪种方式,由于电子邮件,它看起来是多余的。
      • 知道了--是的,我实际上只是从用户名中删除了 unique=True ,这似乎可以解决问题...我想保留它以提高灵活性。感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2015-08-10
      • 1970-01-01
      相关资源
      最近更新 更多