0

I've coded my own AbstractBaseUser and BaseUserManager. Creating users and superusers via terminal works fine. But there is a problem with creating users via form. All user fields are saved properly except password field, which is not hashed (while using set_password()). My models.py:

from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager


class MyUserAccountManager(BaseUserManager):
    def create_superuser(self, email, first_name, last_name, password, **other_fields):
        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)

        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')

        return self.create_user(email, first_name, last_name, password, **other_fields)

    def create_user(self, email, first_name, last_name, password, **other_fields):
        if not email or not first_name or not last_name or not password:
            raise ValueError('You must provide more data')

        email = self.normalize_email(email)
        user = self.model(email=email, first_name=first_name, last_name=last_name, **other_fields)
        user.set_password(password)
        user.save()
        return user


class MyUser(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField('Email address', unique=True, max_length=30)
    first_name = models.CharField('First name', max_length=30)
    last_name = models.CharField('Last name', max_length=30)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    objects = MyUserAccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return self.email

And my forms.py:

from django import forms
from .models import MyUser

class MyUserForm(forms.ModelForm):
    email = forms.CharField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    last_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last name', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password', 'autocomplete': 'off', 'style': 'margin-top: 0.4em; margin-bottom: 1em'}))
    
    class Meta:
        model = MyUser
        fields = ['email',
                  'first_name',
                  'last_name',
                  'password']

I think there is no need to show views.py and html file (full standard). my form Any help is appreciated!

1 Answer 1

1

The * is coming from crispy-forms. From the crispy-form docs...

If you don’t like the use of * (asterisk) to denote required fields you have two options:

Asterisks have an asteriskField class set. So you can hide it using CSS rule:

.asteriskField {
    display: none;
}

Override field.html template with a custom one.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.