I want logged in user redirect to index when they attempt to go to the register form.
I manage to do to that, but I can't validate the register form when the a user who is not logged in complete it.
I have a custom view for signup:
class SignupView(UserPassesTestMixin, FormView):
template_name = 'main/auth/register.html'
form_class = forms.UserCreationForm
def test_func(self):
self.request.user.is_authenticated
def handle_no_permission(self):
if self.request.user.is_authenticated:
return redirect('main:index')
return self.get(self.request)
def get_success_url(self):
redirect_to = self.request.GET.get`enter code here`('next', 'main:index')
return redirect_to
def form_valid(self, form):
response = super().form_valid(form)
form.save()
email = form.cleaned_data.get('email')
first_name = form.cleaned_data.get('first_name')
raw_password = form.cleaned_data.get('password1')
logger.info('Nuevo registro para email=%s a través de SignupView', email)
user = authenticate(email=email, password=raw_password)
login(self.request, user)
form.send_mail()
return response
methods
test_func(self) and handle_no_permission(self) are used to test if the user is authenticated
but I think the problem is in return self.get(self.request) I use it to load the form but when I submit the form with correct data, it POST it to validate it, but just reload it again. I suppose I have to call form_valid but I can't figure out how.
Any help would be appreciated!! Regards
You can use the dispatch method of django CBV. Like below.
class SignupView(UserPassesTestMixin, FormView):
template_name = 'main/auth/register.html'
form_class = forms.UserCreationForm
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated:
return redirect('main:index')
return super().dispatch(request, *args, **kwargs)
# other methods
This is function based views and its simple
views.py
to register
def register(request):
if request.user.is_authenticated:
return redirect(reverse('post_list'))
else:
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
new_user = user_form.save(commit=False)
new_user.set_password(
user_form.cleaned_data['password1']
)
new_user.save()
Profile.objects.create(user=new_user)
return render(
request,
'account/register_done.html',
{'new_user': new_user}
)
else:
user_form = UserRegistrationForm()
return render(
request,
'account/register.html',
{'user_form': user_form}
)
forms.py
class UserRegistrationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput(attrs={
'class': 'myfieldclass',
'placeholder': 'Password ...',
'type': 'password',
'name': 'password'
}))
password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput(attrs={
'class': 'myfieldclass',
'placeholder': 'Repeat Password ...',
'type': 'password',
'name': 'password'
}))
username = forms.CharField(label='Username', widget=forms.TextInput(attrs={
'class': 'myfieldclass',
'placeholder': 'Username ...',
'type': 'text',
'name': 'username'
}))
email = forms.CharField(label='Email', widget=forms.EmailInput(attrs={
'class': 'myfieldclass',
'placeholder': 'Email ...',
'type': 'email',
'name': 'email'
}))
class Meta:
model = User
fields = ('username', 'email')
help_texts = {
'username': '',
}
def clean_password2(self):
cd = self.cleaned_data
if cd['password1'] != cd['password2']:
raise forms.ValidationError(
'Passwords dosent Matched.')
return cd['password2']
Related
I have created an extended User model and a form to register it. Since the form is filled out by an admin and not a user, the UserCreationForm has a random password generator to fill out password1 and 2, then set new password. This is great for a new user, but every time an admin edits the user profile, it will set a new password. I've looked at a few dozen examples here and on big G but can't seem to find a usable solution to know if the user has a password set.
I am re-using this form for update view, which is where I don't want the random password to be generated again. I tried doing the same if statement check as the username but it doesn't work the same way as the auth\form.py user.set_password is looking for password1.
class EmployeeRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control mb-2',
'placeholder': 'Email address'}))
first_name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control mb-2',
'placeholder': 'First name'}))
last_name = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control mb-2', 'placeholder': 'Last name'}))
password1 = None
password2 = None
class Meta:
model = User
fields = ['email', 'first_name', 'last_name']
def clean(self):
password = User.objects.make_random_password(length=10,
allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
self.cleaned_data['password1'] = password
self.cleaned_data['password2'] = password
return super().clean()
def save(self, commit=True):
user = super().save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
if user.username == '':
if len(user.first_name.split()) and len(user.last_name.split()) > 1:
username = f'{"".join(user.first_name.split()[:2])}{"."}{"".join(user.last_name.split())}'
elif len(user.first_name.split()) > 1:
username = f'{"".join(user.first_name.split()[:2])}{"."}{user.last_name}'
elif len(user.last_name.split()) > 1:
username = f'{user.first_name}{"."}{"".join(user.last_name.split())}'
else:
username = f'{user.first_name}{"."}{user.last_name}'
username = username.lower()
user.username = username
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
Update
Here is the profile_edit view where I verify the details of an existing user and save changes made through the form.
#login_required()
def profile_edit(request, slug, *args, **kwargs):
"""
Used for updating the Employee profile
"""
employee = Employee.objects.get(slug=slug)
employee_user = User.objects.get(id=employee.user.id)
form = EmployeeForm(request.POST or None, request.FILES or None, instance=employee)
user_form = EmployeeRegistrationForm(request.POST or None, instance=employee_user)
if 'cancel' in request.POST:
return redirect('corehr:employees')
elif request.method == 'POST':
form = EmployeeForm(request.POST or None, request.FILES or None, instance=employee)
user_form = EmployeeRegistrationForm(request.POST or None, instance=employee_user)
if form.is_valid() and user_form.is_valid():
form.save(commit=False)
user_form.save()
form.save()
messages.success(request, f'{employee.get_full_name}{" was updated successfully."}')
return redirect(reverse_lazy('corehr:profile', kwargs={'slug': slug}))
else:
messages.error(request, 'Please correct the errors listed below')
else:
form = EmployeeForm(request.POST or None, request.FILES or None, instance=employee)
user_form = EmployeeRegistrationForm(request.POST or None, instance=employee_user)
context = {'form': form, 'user_form': user_form}
return render(request, 'coreHR/profile_edit.html', context)
I ended up taking the suggestions from Abdul and Ranu. The are both right, so I just created a UserUpdateForm to update the data rather to 're-create' the user again. It all works as smooth as ever.
class UserUpdateForm(forms.ModelForm):
class Meta:
model = User
fields = ['email', 'first_name', 'last_name']
widgets = {
'email': forms.EmailInput(attrs={'class': 'form-control mb-2'}),
'first_name': forms.TextInput(
attrs={'class': 'form-control mb-2'}),
'last_name': forms.TextInput(
attrs={'class': 'form-control mb-2'}),
}
I replaced the reference in the profile_edit view from EmployeeRegistrationForm to UserUpdateForm. This was so simple an I was busting my head trying to work around several complex solutions which were going against the basics.
User = get_user_model()
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','phone' , 'password',)
write_only_fields = ('password',)
def create(self, validated_data):
user = User.objects.create(validated_data['phone'])
user.set_password(validated_data['password'])
user.save()
return user
})
class Register(APIView):
def post(self, request, *args, **kwargs):
phone = request.data.get('phone', False)
password = request.data.get('password', False)
print(phone)
print(password)
if phone and password:
old = PhoneOTP.objects.filter(phone__iexact=phone)
if old.exists():
old = old.first()
validated = old.validate
if validated:
temp_data = {
'phone': phone,
'password': password
}
serializers = CreateUserSerializer(data=temp_data)
serializers.is_valid(raise_exception=True)
user = serializers.save()
old.delete()
return Response({
'status': True,
'detail': 'Account is created '
})
while saving user pasword feild is shows Invalid password format or unknown hashing algorithm.
user is created the password feild is Invalid password format or unknown hashing algorithm.
uable to find y
also tried user.set_unusable_password() in serializer but same result could not figure it out
I try a lot a method you are using. It didn't save the password in the right form.
I suggest you create another model such as Profile and serializers for it and then try this -:
views.py
class Register(APIView):
permission_classes = (AllowAny, )
serializer_class = UserRegistrationSerializer
def post(self, request, *args, **kwargs):
phone = request.data.get('phone' , False)
if phone:
old = PhoneOTP.objects.filter(phone__iexact = phone)
if old.exists():
old = old.last()
validated = old.validated
if validated:
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
response = {
'success' : 'True',
'status code' : status.HTTP_200_OK,
'message': 'User registered successfully',
}
status_code = status.HTTP_200_OK
return Response(response, status=status_code)
else:
return Response({
'status' : False,
'detail' : "OTP haven't verified. FIrst do that step."
})
else:
return Response({
'status' : False,
'detail' : 'Please verify phone number first.'
})
else:
return Response({
'status' : False,
'detail' : 'Phone password, address, Date_Of_Birth, are not sent.'
})
serializers.py
class UserRegistrationSerializer(serializers.ModelSerializer):
profile = ProfileSerializer(required=False)
class Meta:
model = User
fields = ('phone', 'username', 'password', 'profile')
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create_user(**validated_data)
users = Profile.objects.create(
user=user,
state=profile_data['state'],
city=profile_data['city'],
date_Of_Birth=profile_data['date_Of_Birth'],
address=profile_data['address']
)
users.save()
return users
Hope the answer is useful
I know there are hundreds of posts about that topic but, in all of them, there is something slightly different from my own program and I can't adapt it to my program because the Django way of handling password is such a mess that I understand nothing. A little help would be greatly appreciated, I thank you in advance.
So, when a new user registers, everything works perfectly but, somehow, the password is not saved in the database. When I go to the admin interface, it tells me that the password format is invalid or the hashag function is not known.
Here is my code :
Forms.py
class InscriptionForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email', 'password']
widgets = {'username': forms.TextInput(attrs={'class': 'form-control'}),
'first_name': forms.TextInput(attrs={'class': 'form-control'}),
'last_name': forms.TextInput(attrs={'class': 'form-control'}),
'email': forms.EmailInput(attrs={'class': 'form-control'}),
'password': forms.PasswordInput(attrs={'class': 'form-control'})}
def clean_password(self):
password = self.cleaned_data['password']
try:
validate_password(password, user=self)
except forms.ValidationError:
self.add_error('password', password_validators_help_texts())
return password
Views.py
def inscription(request):
if request.method == "POST":
form = InscriptionForm(request.POST)
if form.is_valid():
new_user = form.save()
authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
login(request, new_user)
request.session['is_connected'] = True
return redirect(inscription_suite)
else:
form = InscriptionForm()
return render(request, 'inscription/inscription.html', {'form': form})
I already tried modifying the view like this :
def inscription(request):
if request.method == "POST":
form = InscriptionForm(request.POST)
if form.is_valid():
new_user = form.save(commit=False)
new_user.password = make_password(form.cleaned_data['password'])
authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
login(request, new_user)
new_user.save()
request.session['is_connected'] = True
return redirect(inscription_suite)
else:
form = InscriptionForm()
return render(request, 'inscription/inscription.html', {'form': form})
But it raises the following error ValueError at /inscription
Cannot force an update in save() with no primary key.
Can someone help me please ?
Thanks in advance !
You must save password using set_password().
def inscription(request):
if request.method == "POST":
form = InscriptionForm(request.POST)
if form.is_valid():
new_user = form.save(commit=False)
password = form.cleaned_data['password'] # get password
new_user.set_password(password) # set the password
new_user.save() # save the user
authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
login(request, new_user)
request.session['is_connected'] = True
return redirect(inscription_suite)
else:
form = InscriptionForm()
return render(request, 'inscription/inscription.html', {'form': form})
I want to do ajax form validation to display errors. I looked at many examples, but some are old and do not work, while others I do not understand.Below is the code, please help with the implementation of ajax requests.
views.py
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(user_form.cleaned_data['password'])
# Save the User object
new_user.save()
return HttpResponse('IZI')
else:
print(user_form.errors)
user_form = UserRegistrationForm()
# errors = user_form.errors
data = {'user_form': user_form, 'errors': user_form.errors}
return render(request, 'registration.html', data)
# return HttpResponse(simplejson.dumps(errors))
else:
user_form = UserRegistrationForm()
return render(request, 'registration.html', {'user_form': user_form})
models.py
class TestUser(AbstractUser):
phone = PhoneNumberField(null=False, blank=False, unique=True)
class Meta:
db_table = '"fyzzys"."users"'
forms.py
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password', widget=forms.PasswordInput)
phone = PhoneNumberField(region='RU', required='true')
email = forms.CharField(error_messages='')
class Meta:
model = TestUser
fields = ('username', 'first_name', 'email', 'phone')
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
Here is an example but you'll need to adapt it to your needs and your code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
$.ajax({
url: 'your_url_for_register_view',
data: { password : 'your_password',
password2 : 'your_password',
phone : 'your_phone',
email : 'your_email',
csrfmiddlewaretoken : {{ csrf_token }},
},
success: function (data) {
//do something if successful
}
});
</script>
As per documentation : https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html
i want to create a registration view so, it takes username, password, and email for registration and i am using Django User Model, but it is giving me an error.
AttributeError at /signup/
'SignUpForm' object has no attribute 'cleaned_data'
please tell me how to fix this,
forms.py
class SignUpForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Username'}))
email = forms.EmailField(widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}))
password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}))
confirm_password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder':
'Confirm Password'}), label="Confirm Password")
class Meta:
model = User
def __init__(self, *args, **kwargs):
super(SignUpForm, self).__init__(*args, **kwargs)
self.fields['username'].validators.append(ForbiddenUsernamesValidator)
self.fields['username'].validators.append(InvalidUsernameValidator)
self.fields['username'].validators.append(UniqueUsernameIgnoreCaseValidator)
self.fields['email'].validators.append(UniqueEmailValidator)
def clean(self):
super(SignUpForm, self).clean()
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if password and password != confirm_password:
self._errors['password'] = self.error_class(['Passwords don\'t match'])
return self.cleaned_data
views.py
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
email = form.cleaned_data.get('email')
print(username)
print(password)
print(email)
messages.add_message(request, messages.SUCCESS, 'YOU ARE REGISTRED SUCCESSFULLY')
return render(request, 'authentication/signup.html', {})
else:
return render(request, 'authentication/signup.html', {'form': form})
else:
return render(request, 'authentication/signup.html', {'form': SignUpForm})
def clean(self):
self.cleaned_data = super(SignUpForm, self).clean()
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if password and password != confirm_password:
self._errors['password'] = self.error_class(['Passwords don\'t match'])
return self.cleaned_data