Search code examples
pythondjangonullconstraintsdjango-authentication

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


I can't create the superuser when I create this model in my app.
WHen I remove AUTH_USER_MODEL = 'app.User' from my settings then showing another error "django.core.exceptions.FieldError: Unknown field(s) (full_name) specified for User" but I can create superuser on that time. Even I tried to fill up every single field with "null=True" and solved the error but can't log in to my admin panel with the created email password. I can't understand exactly where was the problem.
. enter image description here

Here is my all code.

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

When I'm going to create superuser then showing the following error

(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

Solution

  • Your zip field can't be null and you are not setting any value for it when creating a new user/superuser. Add null=True, a default value or set it when creating a new user.

    Also, zip is a python built-in function, you might want to rename the field to zip_code or something like that.

    Regarding not being able to login to the admin panel with an already created account is probably because you are setting staff instead of the is_staff flag required to access the admin. I recommend using the default naming.

    Check the full example in the documentation.