I'm learning Django and tried to write my own custom user model. I'm not using DRF and serializers and stuffs I have no idea about :) I am using createView to create users but I can't login because "Invalid password." I checked the user's password in admin and the user's password is "Invalid password format or unknown hashing algorithm." .
here are the codes: Custome User and User Manager in models
class UserManager(UserManager):
def create_user(self, username, email, password, **extra_fields):
if not email:
raise ValueError('User must have email')
if not username:
raise ValueError('User must have username')
user = User.objects.create_user(
username=username,
email=self.normalize_email(email),
)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password, **extra_fields) :
user = self.create_user(username, email, password)
user.is_staff = True
user.is_superuser = True
user.is_admin = True
user.is_active = True
user.save()
return user
class User(AbstractBaseUser):
username = models.CharField(unique=True, max_length=200)
email = models.EmailField(unique=True)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
modified_at = models.DateTimeField(auto_now=True)
objects = UserManager()
REQUIRED_FIELDS = ["username","email", "password"]
USERNAME_FIELD = "username"
def __str__(self):
return self.email
def has_perm(self, perm, object=None):
"Does the user have a specific permission?"
return self.is_admin
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
SignUp and login in views
class SignUp(CreateView):
model = User
form_class = CUForm
success_url = reverse_lazy('index')
def login(request):
if request.user.is_authenticated:
messages.warning(request, 'You are already logged in.')
return redirect('/list')
elif request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return redirect('/list')
else:
try:
user = User.objects.get(username=username)
messages.error(request, 'Invalid password.')
except:
messages.error(request, 'Invalid username ')
return redirect('login')
return render(request, 'accounts/login.html')
and forms.py
class CUForm(forms.ModelForm):
username = forms.CharField(max_length=200)
email = forms.EmailField(widget=forms.EmailInput())
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ['email','username','password',]
def clean(self):
cleaned_data = super(CUForm, self).clean()
password = cleaned_data.get('password')
confirm_password = cleaned_data.get('confirm_password')
if password != confirm_password:
raise forms.ValidationError('Password does not match.')
and admin
class CostumeUserAdmin(UserAdmin):
list_display = ('email', 'username', 'is_active', 'is_admin')
filter_horizontal = ()
list_filter = ('is_staff',)
fieldsets = ()
admin.site.register(User, CostumeUserAdmin)
I have read some of the solutions and I changed
user = self.model(
username=username,
email=self.normalize_email(email)
)
to
user = User.objects.create_user(
username=username,
email=self.normalize_email(email),
)
Alrigh I have fixed the "Invalid password format or unknown hashing algorithm." issue by adding this to my createView:
def form_valid(self, form):
user = form.save(commit=False)
password = self.request.POST['password']
user.set_password(password)
user.save()
return super().form_valid(form)
and the password now saves correctly, not sure why but it does. And then I realized I didn't add AUTH_USER_MODEL = 'accounts.User' in my setting.py! I still don't know why I need to use set_password in form_valid even tho I used it in UseManager but now It works!