Django custom user creation not displaying custom fields in admin site

I'm trying to create a cutom user in my Django with custom fields like first_name, last_name, date_of_birth, gender, email, etc. So for this I have overridden AbstractBaseUser

for my custom user UserCreationForm

to create a new user and UserChangeForm

change the values ​​of the user fields.

Models.py

    class AppUserManager(BaseUserManager):
        """
        Manager for class AppUser
        """

        def _create_user(self, username, password, first_name, last_name,
                         date_of_birth, email, gender, is_staff, is_superuser,
                         **extra_fields):
            """
            Creates and saves a User with the given username, email and password.
            """
            now = timezone.now()
            if not username:
                raise ValueError('The given username must be set')
            email = self.normalize_email(email)
            user = self.model(username=username,
                              first_name=first_name, last_name=last_name,
                              date_of_birth=date_of_birth, email=email, gender=gender,
                              is_staff=is_staff, is_active=True,
                              is_superuser=is_superuser, last_login=now,
                              date_joined=now, **extra_fields)
            user.set_password(password)
            user.save(using=self._db)
            return user

        def create_user(self, username, password, first_name, last_name, date_of_birth, email, gender, **extra_fields):
            return self._create_user(username, password, first_name, last_name,
                                     date_of_birth, email, gender, False, False,
                                     **extra_fields)

        def create_superuser(self, username, password, first_name, last_name, date_of_birth, email, gender, **extra_fields):
            return self._create_user(username, password, first_name, last_name,
                                     date_of_birth, email, gender, True, True,
                                     **extra_fields)


    class AppUser(AbstractBaseUser, PermissionsMixin):
        """
        User for Application
        """

        username = models.CharField(verbose_name='username', max_length=30, unique=True,
                                    help_text='Required. 30 characters or fewer. Letters, digits and '
                                              '@/./+/-/_ only.',
                                    validators=[
                                        validators.RegexValidator(r'^[\w.@+-]+$', 'Enter a valid username.', 'invalid')
                                    ])

        first_name = models.CharField(verbose_name='first name', max_length=30)

        last_name = models.CharField(verbose_name='last name', max_length=30)

        date_of_birth = models.DateField(verbose_name='birth date')

        email = models.EmailField(verbose_name='email address', unique=True)

        GENDER_CHOICES = (
            ('m', 'Male'),
            ('f', 'Female'),
        )
        gender = models.CharField(verbose_name='gender', max_length=1, choices=GENDER_CHOICES)

        is_staff = models.BooleanField(verbose_name='staff status', default=False,
                                       help_text='Designates whether the user can log into this admin '
                                                 'site.')
        is_active = models.BooleanField(verbose_name='active status', default=True,
                                        help_text='Designates whether this user should be treated as '
                                                  'active. Un select this instead of deleting accounts.')
        date_joined = models.DateTimeField(verbose_name='date joined', default=timezone.now)

        objects = AppUserManager()

        USERNAME_FIELD = 'username'
        REQUIRED_FIELDS = ['first_name', 'last_name', 'date_of_birth', 'email', 'gender']

        class Meta:
            verbose_name = 'user'
            verbose_name_plural = 'users'
            db_table = 'app_users'

        def get_full_name(self):
            """
            Returns the first_name plus the last_name, with a space in between.
            """
            full_name = '%s %s' % (self.first_name, self.last_name)
            return full_name.strip()

        def get_short_name(self):
            """Returns the short name for the user."""
            return self.first_name

        def email_user(self, subject, message, from_email=None, **kwargs):
            """
            Sends an email to this User.
            """
            send_mail(subject, message, from_email, [self.email], **kwargs)

      

admin.py

    class CustomUserCreationForm(UserCreationForm):
        """
        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)
        first_name = forms.CharField(label='First Name')  # Custom Required Field. and other fields should go same way 

        class Meta(UserCreationForm.Meta):
            model = AppUser
            fields = ('username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender')

        def clean_username(self):
            username = self.cleaned_data["username"]

            try:
                AppUser.objects.get(username=username)
            except AppUser.DoesNotExist:
                return username
            raise forms.ValidationError(self.error_messages['duplicate_username'])

        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 do not match.")
            return password2

        def save(self, commit=True):
            # Save the provided password in hashed format
            user = super(UserCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                user.save()
            return user


    class CustomUserChangeForm(UserChangeForm):
        password = ReadOnlyPasswordHashField(label="password",
                                             help_text="""Raw passwords are not stored, so there is no way to see this
                                             user password, but you can change the password using <a href=\"password/\">
                                             this form</a>.""")

        class Meta(UserChangeForm.Meta):
            model = AppUser
            fields = (
                'username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender',
                'password', 'is_active', 'is_staff', 'is_superuser', 'user_permissions'
            )

        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 AppUserAdmin(UserAdmin):
        """

        """
        form = CustomUserChangeForm
        add_form = CustomUserCreationForm

        list_display = ('username', 'first_name', 'last_name', 'email',)
        list_filter = ('is_superuser',)

        fieldsets = (
            (None, {'fields': (
                'username', 'first_name', 'last_name', 'date_of_birth', 'email', 'gender',
            )}),
            ('Permissions', {'fields': (
                'is_active', 'is_superuser', 'is_staff',
            )}),
        )

        search_fields = ('username', 'email', 'first_name', 'last_name',)
        ordering = ('username', 'email',)


    admin.site.register(AppUser, AppUserAdmin)

      

I created a superuser from the command line. But in the form for adding a user, only the fields "Username", "Password" and "Confirm password" are displayed. enter image description here

So how can I get the fields to create a custom form displaying the required fields?

After submitting it gives me an error:

Exception Type: IntegrityError at /admin/users/appuser/add/
Exception Value: Column 'date_of_birth' cannot be null

      

+3


source to share


1 answer


This is the correct form to add a user. Since the help text is formulated on top of the form, the username and password are set first, then you will see the rest of the fields. If you are editing an existing user, you will see everything as well.



0


source







All Articles