I am new to Django I am trying to get access to form.save()
using form = self.form_class(request.POST)
but I have been having to use methods like self.get_form_class()
to access form.is_valid()
and form.save()
but cannot get method set_password()
from user = form.save(commit=False)
I am not sure what the problem is. Why cant I access user.set_password()
? Even when I try to create a BaseUserManager
self.model()
does not give me a definition for user.set_password()
or user.save()
why is this?
# views.py
class RegistrationView(CreateView):
template_name = "AskQuestions/customuser_form.html"
form_class = RegistrationForm
model = CustomUser
success_url = "questions/login"
def get(self, request, *args, **kwargs):
form = self.get_form_class()
form = form(initial=self.initial)
return render(request, self.template_name, {"form": form})
def post(self, request):
form = self.get_form_class()
form = form(request.POST)
if (form.is_valid()):
user = form.save(commit=False)
# user.set_password() no definition
user.set_password()
messages.add_message(request, messages.SUCCESS, "Your account has been successfully created.")
return redirect("AskQuestions:login")
else:
return render(request, self.template_name, {"form": form})
# models.py
class CustomUser(AbstractUser):
phone_number = models.CharField(max_length=20)
REQUIRED_FIELDS = ["first_name", "last_name", "phone_number"]
# forms.py
class RegistrationForm(forms.ModelForm):
confirm_password = forms.CharField(label="Confirm password:", max_length=200, widget=forms.PasswordInput(attrs={"class": "form-control"}))
class Meta:
model = CustomUser
fields = ["first_name", "last_name", "username", "phone_number", "password",]
labels = {
"first_name": "Name:",
"last_name": "Last name:",
"username": "Username",
"phone_number": "Phone number:",
"password": "Password",
"confirm_password": "Confirm password:",
}
widgets = {
"first_name": forms.TextInput(attrs={"class": "form-control"}),
"last_name": forms.TextInput(attrs={"class": "form-control"}),
"username": forms.TextInput(attrs={"class": "form-control"}),
"phone_number": forms.TextInput(attrs={"class": "form-control"}),
"password": forms.PasswordInput(attrs={"class": "form-control"}),
}
def clean(self):
data = self.cleaned_data
first_name = data["first_name"]
last_name = data["last_name"]
username = data["username"]
password = data["password"]
confirm_password = data["confirm_password"]
if not first_name:
raise forms.ValidationError("You must supply a name.")
if not last_name:
raise forms.ValidationError("You must supply a last name.")
if not username:
raise forms.ValidationError("You must supply a username.")
else:
username_exists = CustomUser.objects.filter(username=username).exists()
if (username_exists):
self.add_error("username", "This username has already been taken.")
if not password:
raise forms.ValidationError("You must supply a password.")
if not confirm_password:
raise forms.ValidationError("You must supply a password to compare against.")
if not password == confirm_password:
raise forms.ValidationError("Passwords do not match.")
return data
CodePudding user response:
- You could create
RegistrationForm
inherited fromUserCreationForm
# forms.py
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ("first_name", "last_name", "username", "phone_number",)
regarding clean
method - you dont have to check if user send some certain field, just in your CustomUser model you have to add those fields without null=True
, blank=True
. as an example:
class CustomUser(AbstractUser):
first_name = models.CharField(_("first name"), max_length=150)
and now i could delete checks for first_name in your Registration form clean-method. As result of this refactoring - clean-method should be deleted.
Dont worry about confirm_password
field, it exists in UserCreationForm but called as password2
, original password called as password1
. and checks for password in this form also exists
- Answer for your question with the
set_password
from the previous point we got a form inherited fromUserCreationForm
which have thisset_password
logic already written in save method. You just need to callform.save()
so your post-method in view:
def post(self, request):
form = self.get_form_class()
form = form(request.POST)
if form.is_valid():
form.save()
messages.add_message(request, messages.SUCCESS, "Your account has been successfully created.")
return redirect("AskQuestions:login")
return render(request, self.template_name, {"form": form})