Custom User Model (models.py):
class Users(AbstractBaseUser):
user_id = models.AutoField(primary_key=True)
user_email = models.EmailField(max_length=100, unique=True)
password = models.CharField(max_length=100)
registration_date = models.DateField(auto_now_add=True)
last_login = models.DateField(auto_now_add=True)
is_administrator = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
email_verified = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'user_email'
Custom User Manager (models.py)
class UserManager(BaseUserManager):
def create_user(self, user_email, password):
user = self.model(
email=self.normalize_email(user_email)
)
user.set_password(password)
user.save(using=self._db)
return user
Registration Form (forms.py):
class RegistrationForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
password_confirm = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = get_user_model()
fields = ('user_email',)
def clean_password(self):
password1 = self.cleaned_data.get("password")
password2 = self.cleaned_data.get("password_confirm")
if password1 and password2 and password1 != password2:
raise forms.ValidationError( self.error_messages['password_mismatch'],
code='password_mismatch' )
return password2
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.registration_date = datetime.date.today()
user.last_login = datetime.date.today()
user.set_password("password")
if commit:
user.save()
return user
Register view (views.py)
def register(request):
if request.method == "POST":
form = RegistrationForm(request.POST)
if form.is_valid:
form.save()
else:
form = RegistrationForm()
return render(request, 'web/page.html', {'form' : form})
This is my first question on .. anything online (I'm an avid user of the search facility), but I've been struggling with this for days and I feel like it shouldn't be so difficult.
For my question, it is more like a two part query.
1) I want a custom user model, but want to use as much of what Django is offering. But getting rid of the username field and adding a couple other fields seems to require me to make "custom" everything else. Including a custom user manager and custom forms - not ideal! The registration form above works but I was hoping for something a bit more simple, along the lines of:
class RegistrationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = get_user_model()
fields = ('user_email', 'password1', 'password2')
but I seem to be struggling, running it gives me the error:
The Users could not be created because the data didn't validate.
Ideally I would want something simple like that without the error. I'm hoping it to give fewer errors and hopefully more future proof if Django adds new security features.
2) Why tf won't the login code below work?
Login Form (forms.py):
class LoginForm(forms.Form):
user_email = forms.EmailField(max_length=100)
password = forms.CharField(max_length=100)
Login View (views.py):
def login_user(request):
if request.method == "POST":
user_email = request.POST.get('email')
password = request.POST.get('password')
UserModel = get_user_model()
user = UserModel.objects.get(user_email=user_email)
if user.check_password(password):
login(request, user)
return render(request, 'login.html')
I'm pretty sure the problem lies with the second if statement. It just won't give a True value when the correct password is entered. Having tried print(user.user_id), the correct id is given for the email and password entered. Having played with some plaintext passwords, it works, but I rather like the set_password and check_password functions - provided they work!
Many thanks!