Password and User settings Form implemented
This commit is contained in:
parent
b63cfaa741
commit
f31771b588
72
forms.py
72
forms.py
@ -1,7 +1,9 @@
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
|
||||
from .models import UserProfile
|
||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, PasswordChangeForm
|
||||
from django.utils.translation import gettext as _
|
||||
from .models import UserProfile, get_userprofile
|
||||
from users import emails
|
||||
|
||||
|
||||
class UserRegistrationForm(UserCreationForm):
|
||||
@ -24,6 +26,72 @@ class UserProfileFormLanguageOnly(forms.ModelForm):
|
||||
fields = ['language_code']
|
||||
|
||||
|
||||
class UserPasswordChangeForm(PasswordChangeForm):
|
||||
email = forms.EmailField()
|
||||
first_name = forms.CharField(max_length=150)
|
||||
last_name = forms.CharField(max_length=150)
|
||||
field_order = ["email", "first_name", "last_name", "old_password", "new_password1", "new_password2"]
|
||||
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
#
|
||||
data = request.POST or {'email': request.user.email, 'first_name': request.user.first_name, 'last_name': request.user.last_name}
|
||||
#
|
||||
super().__init__(request.user, data)
|
||||
self.fields['old_password'].widget.attrs.update({'autofocus': False})
|
||||
self.fields['old_password'].required = False
|
||||
|
||||
def clean_old_password(self):
|
||||
"""
|
||||
Validation of old_password field only, if set.
|
||||
"""
|
||||
old_password = self.cleaned_data["old_password"]
|
||||
if old_password and not self.user.check_password(old_password):
|
||||
raise forms.ValidationError(
|
||||
self.error_messages["password_incorrect"],
|
||||
code="password_incorrect",
|
||||
)
|
||||
return old_password
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
Validation of new_passwords only if old_password field is set.
|
||||
"""
|
||||
clean_data = forms.Form.clean(self)
|
||||
old_password = clean_data.get('old_password')
|
||||
#
|
||||
if old_password:
|
||||
self.validate_passwords("new_password1", "new_password2")
|
||||
self.validate_password_for_user(self.user, "new_password2")
|
||||
return forms.Form.clean(self)
|
||||
|
||||
def save(self, commit=True):
|
||||
changed = False
|
||||
for key in self.fields:
|
||||
new = self.data.get(key)
|
||||
try:
|
||||
old = getattr(self.user, key)
|
||||
except AttributeError:
|
||||
pass # Is a password field
|
||||
else:
|
||||
if new != old:
|
||||
if key == 'email':
|
||||
emails.send_validation_mail(self.user, self.request)
|
||||
up = get_userprofile(self.user)
|
||||
up.mail_pending = new
|
||||
up.save()
|
||||
else:
|
||||
changed = True
|
||||
setattr(self.user, key, new)
|
||||
if self.data.get('new_password1'):
|
||||
changed = True
|
||||
self.user.set_password(self.data.get('new_password1'))
|
||||
#
|
||||
if changed:
|
||||
self.user.save()
|
||||
return changed
|
||||
|
||||
|
||||
class UserActivationForm(UserChangeForm):
|
||||
password = None
|
||||
|
||||
|
18
migrations/0004_userprofile_mail_pending.py
Normal file
18
migrations/0004_userprofile_mail_pending.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.2 on 2024-10-27 17:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('users', '0003_userprofile_mail_validated'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='mail_pending',
|
||||
field=models.EmailField(max_length=254, null=True),
|
||||
),
|
||||
]
|
@ -30,6 +30,7 @@ class UserProfile(models.Model):
|
||||
timezone = models.CharField(max_length=150, default='UTC', choices=[(t, t) for t in pytz.common_timezones])
|
||||
language_code = models.CharField(max_length=150, default='en', choices=settings.LANGUAGES)
|
||||
mail_validated = models.BooleanField(default=False)
|
||||
mail_pending = models.EmailField(null=True)
|
||||
|
||||
def export_key(self):
|
||||
return self.user.username
|
||||
|
@ -4,7 +4,14 @@
|
||||
{% block content %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{% include 'users/profile_formdata.html' %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<h1>{% trans "Language and Timezone" %}</h1>
|
||||
{{ form_userprofile.as_p }}
|
||||
|
||||
<h1>{% trans "Userdata and Password" %}</h1>
|
||||
{{ form_userchange.as_p }}
|
||||
|
||||
<input type="submit" value="{% trans "Save" %}" class="button" />
|
||||
</form>
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<h1>{% trans "Language and Timezone" %}</h1>
|
||||
{{ form_userprofile.as_p }}
|
||||
</select>
|
45
views.py
45
views.py
@ -11,7 +11,7 @@ from django.contrib.auth.models import User
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.http import urlsafe_base64_decode
|
||||
from django.utils.translation import gettext as _
|
||||
from .forms import UserRegistrationForm, UserProfileForm, UserActivationForm
|
||||
from .forms import UserRegistrationForm, UserProfileForm, UserActivationForm, UserPasswordChangeForm
|
||||
import logging
|
||||
from .models import get_userprofile
|
||||
from themes import Context
|
||||
@ -28,35 +28,26 @@ def password_recovery(request):
|
||||
return redirect(request.GET.get('next') or '/')
|
||||
|
||||
|
||||
def profile_post_actions(request, context):
|
||||
if request.POST:
|
||||
form = context.get('form_userprofile')
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return redirect(request.GET.get('next') or '/')
|
||||
|
||||
|
||||
def profile_pre_actions(request, context, form_to_be_used=UserProfileForm):
|
||||
profile = get_userprofile(request.user)
|
||||
if request.POST:
|
||||
form = form_to_be_used(request.POST, instance=profile)
|
||||
else:
|
||||
form = form_to_be_used(instance=profile)
|
||||
context['form_userprofile'] = form
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
context = Context(request) # needs to be executed first because of time mesurement
|
||||
profile_pre_actions(request, context)
|
||||
response = profile_post_actions(request, context)
|
||||
if response is not None:
|
||||
return response
|
||||
profile = get_userprofile(request.user)
|
||||
if request.POST:
|
||||
form_userprofile = UserProfileForm(request.POST, instance=profile)
|
||||
form_userchange = UserPasswordChangeForm(request)
|
||||
if form_userprofile.is_valid() and form_userchange.is_valid():
|
||||
form_userprofile.save()
|
||||
form_userchange.save()
|
||||
return redirect(request.GET.get('next') or '/')
|
||||
else:
|
||||
form_userprofile = UserProfileForm(instance=profile)
|
||||
form_userchange = UserPasswordChangeForm(request)
|
||||
context_adaption(
|
||||
context,
|
||||
request,
|
||||
_('Profile for %(username)s') % {'username': request.user.username},
|
||||
form_userprofile=form_userprofile,
|
||||
form_userchange=form_userchange,
|
||||
)
|
||||
return render(request, 'users/profile.html', context=context)
|
||||
|
||||
@ -158,6 +149,16 @@ def validate(request, uidb64, token):
|
||||
myuser = None
|
||||
|
||||
if myuser is not None and generate_token.check_token(myuser, token):
|
||||
up = get_userprofile(myuser)
|
||||
if up.mail_pending:
|
||||
# change of email-address
|
||||
myuser.email = up.mail_pending
|
||||
myuser.save()
|
||||
up.mail_pending = None
|
||||
up.save()
|
||||
messages.success(request, _("Your new email address is now active."))
|
||||
return redirect("/")
|
||||
else:
|
||||
# Store mail validation to user profile
|
||||
profile = get_userprofile(myuser)
|
||||
profile.mail_validated = True
|
||||
|
Loading…
x
Reference in New Issue
Block a user