django.db.utils.IntegrityError: NOT NULL constraint failed: app_user.zip

django.db.utils.IntegrityError: NOT NULL constraint failed: app_user.zip

我在我的应用程序中创建此模型时无法创建超级用户。
当我从我的设置中删除 AUTH_USER_MODEL = 'app.User' 然后显示另一个错误“django.core.exceptions.FieldError:为用户指定的未知字段(full_name)”但我可以创建超级用户那时。即使我尝试用“null=True”填写每个字段并解决了错误,但无法使用创建的电子邮件密码登录到我的管理面板。我无法准确理解问题出在哪里。

这是我的全部代码。

Models.py

    from django.db import models
    from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager, PermissionsMixin
    )
    from creditcards.models import CardNumberField, CardExpiryField, SecurityCodeField
    
    
    class UserManager(BaseUserManager):
        def create_user(self, email, full_name, password=None, is_active=True, is_staff=False, is_admin=False):
            if not email:
                raise ValueError("Users must have an Email address.")
            if not password:
                raise ValueError("Users must have a Password")
            if not full_name:
                raise ValueError("Users must have a Full Name")
            user_obj = self.model(
                email = self.normalize_email(email),
                full_name=full_name
            )
            user_obj.set_password(password)
            user_obj.staff = is_staff
            user_obj.admin = is_admin
            user_obj.active = is_active
            user_obj.save(using=self._db)
            return user_obj
    
        def create_staffuser(self, email, full_name, password=None):
            user = self.create_user(
                email,
                full_name,
                password=password,
                is_staff=True
            )
            return user
    
        def create_superuser(self, email, full_name, password=None):
            user = self.create_user(
                email,
                full_name,
                password=password,
                is_staff=True,
                is_admin=False  # will be True
            )
            return user
    
    
    class User(AbstractBaseUser):
        email = models.EmailField(max_length=255, unique=True)
        full_name = models.CharField(max_length=255, blank=True, null=True)
        active = models.BooleanField(default=True) # Can Login
        timestamp = models.DateTimeField(auto_now_add=True)
    
        staff = models.BooleanField(default=False)  # staff user non Superuser
        admin = models.BooleanField(default=False)
        # Address
        address = models.CharField(max_length=355)
        zip = models.IntegerField(blank=True)
        city = models.CharField(max_length=255, blank=False, null=True)
    
        # Payment Method
        cc_number = CardNumberField('card number')
        cc_expiry = CardExpiryField('expiration date')
        cc_code = SecurityCodeField('security code')
    
        USERNAME_FIELD = 'email'  # Username
        # USERNAME_FILED and password are required by default
        REQUIRED_FIELDS = ['full_name'] # 'full_name'
    
        objects = UserManager()
    
        def __str__(self):
            return self.email
    
        def  get_full_name(self):
            return self.email
    
        def get_short_name(self):
            return self.email
    
        def has_perm(self, perm, obj=None):
            return True
    
        def has_module_perms(self, app_label):
            return True
    
        @property
        def is_staff(self):
            return self.staff
    
        @property
        def is_admin(self):
            return self.admin
    
        @property
        def is_active(self):
            return self.active
    

Forms.py

    from django import forms
    from django.contrib.auth.forms import ReadOnlyPasswordHashField
    from django.contrib.auth import get_user_model
    from django.forms import TextInput
    
    
    User = get_user_model()
    
    
    class UserAdminCreationForm(forms.ModelForm):
        """A form for creating new users. Includes all the required
        fields, plus a repeated password."""
        password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
        password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
    
        class Meta:
            model = User
            fields = ('full_name', 'email',)
    
        def clean_password2(self):
            # Check that the two password entries match
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                raise forms.ValidationError("Passwords don't match")
            return password2
    
        def save(self, commit=True):
            # Save the provided password in hashed format
            user = super(UserAdminCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                user.save()
            return user
    
    
    class UserAdminChangeForm(forms.ModelForm):
        """A form for updating users. Includes all the fields on
        the user, but replaces the password field with admin's
        password hash display field.
        """
        password = ReadOnlyPasswordHashField()
    
        class Meta:
            model = User
            fields = ('full_name', 'email', 'password', 'active',)
    
        def clean_password(self):
            # Regardless of what the user provides, return the initial value.
            # This is done here, rather than on the field, because the
            # field does not have access to the initial value
            return self.initial["password"]
    
    
    class RegisterForm(forms.ModelForm):
        """A form for creating new users. Includes all the required
        fields, plus a repeated password."""
        password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
        password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
    
        class Meta:
            model = User
            fields = ('full_name', 'email', 'cc_number', 'cc_expiry', 'cc_code', 'zip', 'city',)
    
            widgets = {
                'full_name': TextInput(attrs={'placeholder': 'Card Holder Name'}),
                'cc_number': TextInput(attrs={'placeholder': 'Card Number'}),
                'cc_code': TextInput(attrs={'placeholder': 'Ex: 123'}),
                'email': TextInput(attrs={'placeholder': 'Email'}),
            }
    
        def clean_password2(self):
            # Check that the two password entries match
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                raise forms.ValidationError("Passwords don't match")
            return password2
    
        def save(self, commit=True):
            # Save the provided password in hashed format
            user = super(RegisterForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            user.active = False # send for admin approval
            if commit:
                user.save()
            return user
    
    
    class LoginForm(forms.Form):
        username = forms.EmailField(label='Email')
        password = forms.CharField(widget=forms.PasswordInput)
    

Settings.py

    ...
    AUTH_USER_MODEL = 'app.User'
    ...

当我要创建超级用户然后显示以下错误

(venv) C:\Users\prose\PycharmProjects\reg4> python manage.py createsuperuser
Email: p@gmail.com
Full name: p da
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: y
Traceback (most recent call last):
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 423, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: NOT NULL constraint failed: app_user.zip

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\prose\PycharmProjects\reg4\manage.py", line 22, in <module>
    main()
  File "C:\Users\prose\PycharmProjects\reg4\manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\core\management\__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\core\management\__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\core\management\base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 79, in execute
    return super().execute(*args, **options)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\core\management\base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 189, in handle
    self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
  File "C:\Users\prose\PycharmProjects\reg4\app\models.py", line 38, in create_superuser
    user = self.create_user(
  File "C:\Users\prose\PycharmProjects\reg4\app\models.py", line 25, in create_user
    user_obj.save(using=self._db)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\contrib\auth\base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\base.py", line 726, in save
    self.save_base(using=using, force_insert=force_insert,
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\base.py", line 763, in save_base
    updated = self._save_table(
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\base.py", line 868, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\base.py", line 906, in _do_insert
    return manager._insert(
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\query.py", line 1270, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1410, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 98, in execute
    return super().execute(sql, params)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\prose\PycharmProjects\reg4\venv\lib\site-packages\django\db\backends\sqlite3\base.py", line 423, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: NOT NULL constraint failed: app_user.zip

您的 zip 字段不能为空,并且您在创建新的 user/superuser 时没有为其设置任何值。添加null=True,默认值或在创建新用户时设置。

此外,zip 是一个 python 内置函数,您可能需要将该字段重命名为 zip_code 或类似名称。

关于无法使用已创建的帐户登录管理面板可能是因为您正在设置 staff 而不是访问管理所需的 is_staff 标志。我建议使用默认命名。

检查文档中的 full example