我试图创建一个视频博客,用户将能够创建自己的帐户和个人资料。我还添加了注册的电子邮件验证。但问题是,当我尝试使用Django 2.2.5开发服务器注册一个新用户时,我得到了这个错误(“复制密钥值违反了唯一的约束”“Actudio PrruleMaBielyNo.MyBykey”细节:密钥(MauliLi数)=()已经存在。反复。我想如果我删除数据库这可能会解决问题。我删除了数据库并创建了另一个。然后我可以创建一个用户,但问题再次出现。我又删除了数据库。这样,我试了很多次,但都解决不了问题。我在谷歌上寻找答案,得到了很多答案,但它们对我来说很难理解,因为我只是在学习过程中。我在Ubuntu 18.04上使用Python 3.6、Django 2.2.5、Postgresql 11。伙计们,你们能看看我的代码,告诉我解决问题的最简单方法吗?提前谢谢!
这是回溯

IntegrityError at /account/register/

duplicate key value violates unique constraint

"account_profile_mobile_number_key"
DETAIL:  Key (mobile_number)=() already exists.
Request Method: POST
Request URL:    http://127.0.0.1:8000/account/register/
Django Version: 2.2.5
Exception Type: IntegrityError
Exception Value:
duplicate key value violates unique constraint "account_profile_mobile_number_key"
DETAIL:  Key (mobile_number)=() already exists.
Exception Location: /media/coduser/2NDTB/ProgramingPROJ/WebDevelopment/DjangoProject/MY-PROJECT/alternative/ex1/myvenv/lib/python3.6/site-packages/django/db/backends/utils.py in _execute, line 84
Python Executable:  /media/coduser/2NDTB/ProgramingPROJ/WebDevelopment/DjangoProject/MY-PROJECT/alternative/ex1/myvenv/bin/python
Python Version: 3.6.8
Python Path:
['/media/coduser/2NDTB/ProgramingPROJ/WebDevelopment/DjangoProject/MY-PROJECT/alternative/ex1',
 '/usr/lib/python36.zip',
 '/usr/lib/python3.6',
 '/usr/lib/python3.6/lib-dynload',
 '/media/coduser/2NDTB/ProgramingPROJ/WebDevelopment/DjangoProject/MY-PROJECT/alternative/ex1/myvenv/lib/python3.6/site-packages']
Server time:    Wed, 11 Sep 2019 01:11:15 +0000

这是帐户模型
from django.db import models
from django.conf import settings
from PIL import Image


class Profile(models.Model):
    GENDER_CHOICES = (
        ('male', 'Male'),
        ('female', 'Female'),
        ('other', 'Other'),
        ('tell you later', 'Tell you later')
    )
    MARITAL_CHOICES = (
        ('married', 'Married'),
        ('unmarried', 'Unmarried'),
        ('single', 'Single'),
        ('divorced', 'Divorced'),
        ('tell you later', 'Tell you later')
    )
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

    date_of_birth = models.DateField(blank=True, null=True)
    gender = models.CharField(
        max_length = 14,
        choices = GENDER_CHOICES,
        default = 'tell you later'
    )
    marital_status = models.CharField(
        max_length = 14,
        choices = MARITAL_CHOICES,
        default = 'tell you later'
    )
    name_of_father = models.CharField(max_length = 30)
    name_of_mother = models.CharField(max_length = 30)
    present_address = models.CharField(max_length = 200)
    permanent_address = models.CharField(max_length = 200)
    mobile_number = models.CharField(max_length = 14, unique = True, db_index=True)
    emergency_contact_number = models.CharField(max_length = 14)
    smart_nid = models.CharField(max_length = 14, unique = True, db_index=True)
    nationality = models.CharField(max_length = 20)
    profile_picture = models.ImageField(default = 'default_profile.jpg', upload_to='users/%Y/%m/%d/')


    def __str__(self):
        return f'{self.user.username} Profile'


    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.profile_picture.path)

        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.profile_picture.path)

这是forms.py
from django import forms
from django.contrib.auth.models import User
from .models import Profile


class BaseForm(forms.Form):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('label_suffix', '')
        super(BaseForm, self).__init__(*args, **kwargs)

class BaseModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('label_suffix', '')
        super(BaseModelForm, self).__init__(*args, **kwargs)


class LoginForm(forms.Form):
    username = forms.CharField(label_suffix='')
    password = forms.CharField(widget=forms.PasswordInput, label_suffix='')


# BaseModelForm has been used instead of forms.ModelForm to remove the colon
class UserRegistrationForm(BaseModelForm):
    password = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Repeat password', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email')
        help_texts = {
            'username': 'Letters, digits and @/./+/-/_ only',
        }


    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError(
                'Please use another Email, that is already taken')
        return email

    def clean_password2(self):
        cd = self.cleaned_data
        if cd['password'] != cd['password2']:
            raise forms.ValidationError('Passwords don\'t match.')
        return cd['password2']

# This will let user to edit their profile
class UserEditForm(BaseModelForm):
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'email')

# This will let user to edit their profile
class ProfileEditForm(BaseModelForm):
    class Meta:
        model = Profile
        fields = ('date_of_birth', 'gender', 'marital_status', 'profile_picture',
                  'name_of_father', 'name_of_mother', 'present_address',
                  'permanent_address', 'mobile_number', 'emergency_contact_number',
                  'smart_nid', 'nationality')

这是帐户应用程序的views.py
from django.http import HttpResponse
from django.shortcuts import render , redirect
from django.contrib.auth import authenticate, login
from django.contrib.auth.decorators import login_required
from .forms import LoginForm, UserRegistrationForm, \
                    UserEditForm, ProfileEditForm

# For email verification
from django.contrib.sites.shortcuts import get_current_site
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from .token_generator import account_activation_token
from django.contrib.auth.models import User
from django.core.mail import EmailMessage
# end of email verification

# User Profile
from .models import Profile
# For flash message
from django.contrib import messages




def user_login(request):
    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            user = authenticate(request,
                                username=cd['username'],
                                password=cd['password'])
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return HttpResponse('Authenticated '\
                                        'successfully')
                else:
                    return HttpResponse('Disabled account')
            else:
                return HttpResponse('Invalid login')
    else:
        form = LoginForm()
    return render(request, 'account/login.html', {'form': form})



def register(request):
    if request.method == 'POST':
        user_form = UserRegistrationForm(request.POST)
        if user_form.is_valid():
            # Create a new user object but avoid saving it yet
            new_user = user_form.save(commit=False)
            new_user.is_active = False # line for email verification

            # Set the chosen password
            new_user.set_password(
                user_form.cleaned_data['password']
            )
            # Save the User object
            new_user.save()
            # Create the user profile
            Profile.objects.create(user = new_user)

            current_site = get_current_site(request)
            email_subject = ' Activate Your Account'
            message = render_to_string('account/activate_account.html', {
                'user': new_user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
                'token': account_activation_token.make_token(new_user),
            })
            to_email = user_form.cleaned_data.get('email')
            email = EmailMessage(email_subject, message, to=[to_email])
            email.send()
            return redirect('account_activation_sent')

    else:
        user_form = UserRegistrationForm()
    return render(request,
                  'account/register.html',
                  {'user_form': user_form})



def account_activation_sent(request):
    return render(request, 'account/account_activation_sent.html')


def account_activation_invalid(request):
    return render(request, 'account/account_activation_invalid.html')


def activate_account(request, uidb64, token):
    try:
        uid = force_bytes(urlsafe_base64_decode(uidb64))
        user = User.objects.get(pk=uid)
    except(TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        login(request, user)
        return redirect('blog-home')
    else:
        return render(request, 'account_activation_invalid.html')


@login_required
def edit(request):
    if request.method == 'POST':
        user_form = UserEditForm(instance=request.user,
                                 data=request.POST)
        profile_form = ProfileEditForm(instance=request.user.profile,
                                       data=request.POST,
                                       files=request.FILES)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            messages.success(request, 'Profile updated successfully')
        else:
            messages.error(request, 'Error updating your profile')
    else:
        user_form = UserEditForm(instance=request.user)
        profile_form = ProfileEditForm(instance=request.user.profile)
    return render(request,
                  'account/profile.html',
                  {'user_form': user_form,
                   'profile_form': profile_form})

这是令牌生成器
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six

class TokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            six.text_type(user.pk) + six.text_type(timestamp) + six.text_type(user.is_active)
        )
account_activation_token = TokenGenerator()

最佳答案

使用空字符串而不将其转换为空字符串是我的错误。事实上,我对Django不太了解,但我正在学习。根据评论部分提供的解决方案-mu太短,我已经能够解决问题。所以功劳归于-穆太短了
对于解决方案,我刚刚在mobile_number字段中添加了一个额外的参数-null=True。就这样。它解决了我的问题。
这是解决办法

mobile_number = models.CharField(max_length = 14, unique = True, db_index=True, null = True)

关于django - 这个问题“重复的键值违反了唯一的约束”已经让我的屁股痛苦了近一个星期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57881034/

10-14 18:23
查看更多