From 35f1b0af7e8adca35aca894b7a95b04c16b46e70 Mon Sep 17 00:00:00 2001 From: Dorian Lesbre <dorian.lesbre@gmail.com> Date: Sat, 6 Mar 2021 10:12:54 +0100 Subject: [PATCH] Added option to update account info --- accounts/admin.py | 2 +- accounts/forms.py | 39 ++++++++++++++++++++++++++-- accounts/templates/profile.html | 2 +- accounts/templates/update.html | 12 +++++++++ accounts/urls.py | 1 + accounts/views.py | 46 ++++++++++++++++++++++++++------- 6 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 accounts/templates/update.html diff --git a/accounts/admin.py b/accounts/admin.py index f9e5b89..0558e42 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -12,7 +12,7 @@ class EmailUserAdmin(admin.ModelAdmin): list_display = ("email", "last_name", "first_name", "is_superuser", "is_active", "email_confirmed",) list_filter = ("is_superuser","is_active", "email_confirmed",) list_editable = ("is_superuser","is_active") - fields = ("email", "last_name", "first_name", "is_superuser", + fields = ("email", "last_name", "first_name", "is_superuser", "is_active", "email_confirmed", ("date_joined", "last_login",), ) ordering = ("last_name", "first_name") diff --git a/accounts/forms.py b/accounts/forms.py index ddbef68..345e9c9 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -1,9 +1,9 @@ +from django import forms from django.contrib.auth.forms import UserCreationForm +from django.utils.safestring import mark_safe from accounts.models import EmailUser -from django.utils.safestring import mark_safe - class FormRenderMixin: """ A mixin that can be included in any form to make it render to html as we want @@ -131,3 +131,38 @@ class CreateAccountForm(FormRenderMixin, UserCreationForm): class Meta: model = EmailUser fields = ('email', 'first_name', 'last_name', 'password1', 'password2',) + +class UpdateAccountForm(FormRenderMixin, forms.ModelForm): + """Form used to update name/email""" + class Meta: + model = EmailUser + fields = ('email', 'first_name', 'last_name') + help_texts = {"email": "Si vous la changez, il faudra confirmer la nouvelle adresse",} + + @staticmethod + def normalize_email(email): + """ Returns a normalized email """ + return email.lower() + + def clean_email(self): + """ Check email uniqueness """ + email = self.cleaned_data["email"] + if email == self.instance.email: + return email + norm_email = self.normalize_email(email) + if EmailUser.objects.filter(email=norm_email).count() > 0: + raise forms.ValidationError( + "Un autre compte avec cette adresse mail existe déjà ." + ) + return norm_email + + def save(self, *args, commit=True, **kwargs): + email = self.cleaned_data["email"] + email_changed = email != self.instance.username + user = super().save(*args, commit=False, **kwargs) + user.username = email + if email_changed: + user.email_confirmed = False + if commit: + user.save() + return user diff --git a/accounts/templates/profile.html b/accounts/templates/profile.html index c814ad4..c2bfd73 100644 --- a/accounts/templates/profile.html +++ b/accounts/templates/profile.html @@ -14,7 +14,7 @@ <p><a href="{% url 'inscription' %}">M'insrire à l'événement</a></p> -<p><a href="TODO">Modifier mes informations</a></p> +<p><a href="{% url 'accounts:update' %}">Modifier mes informations</a></p> <p><a href="TODO">Changer mom mot de passe</a></p> diff --git a/accounts/templates/update.html b/accounts/templates/update.html new file mode 100644 index 0000000..d3c41e8 --- /dev/null +++ b/accounts/templates/update.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} + +{% block "content" %} + <h2>Changer mes informations</h2> + + <form method="post" action="{% url 'accounts:update' %}"> + {% csrf_token %} + {{ form.as_html }} + <br> + <input type="submit" value="Valider"> + </form> +{% endblock %} diff --git a/accounts/urls.py b/accounts/urls.py index 34f4b39..c59f5fc 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -9,5 +9,6 @@ urlpatterns = [ path("logout/", views.LogoutView.as_view(), name="logout"), path("profile/", views.ProfileView.as_view(), name="profile"), path("create/", views.CreateAccountView.as_view(), name="create"), + path("update/", views.UpdateAccountView.as_view(), name="update"), path('activate/<uidb64>/<token>/', views.ActivateAccountView.as_view(), name='activate'), ] diff --git a/accounts/views.py b/accounts/views.py index 9c680b6..48c5499 100644 --- a/accounts/views.py +++ b/accounts/views.py @@ -8,10 +8,10 @@ from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.urls import reverse from django.template.loader import render_to_string -from django.views.generic import RedirectView, TemplateView, View +from django.views.generic import RedirectView, TemplateView, UpdateView, View from django.shortcuts import render, redirect -from accounts.forms import CreateAccountForm +from accounts.forms import CreateAccountForm, UpdateAccountForm from accounts.models import EmailUser from accounts.tokens import email_token_generator from site_settings.models import SiteSettings @@ -69,10 +69,11 @@ class CreateAccountView(View): user = form.save() user.is_active = False # can't login until email validation user.email_confirmed = False + user.save() current_site = get_current_site(request) subject = 'Activation de votre compte Interludes' - message = render_to_string('registration/activation_email.html', { + message = render_to_string('activation_email.html', { 'user': user, 'domain': current_site.domain, 'uid': urlsafe_base64_encode(force_bytes(user.pk)), @@ -80,9 +81,7 @@ class CreateAccountView(View): }) user.email_user(subject, message) - user.save() - - messages.success(request, ('Please Confirm your email to complete registration.')) + messages.info(request, 'Un lien vous a été envoyé par mail. Utilisez le pour finaliser la création de compte.') return redirect('accounts:login') @@ -90,6 +89,8 @@ class CreateAccountView(View): class ActivateAccountView(RedirectView): """Vue d'activation de compte (lien envoyé par mail)""" permanent = False + success_pattern_name = "accounts:profile" + failure_pattern_name = "home" def get_redirect_url(self, uidb64, token, *args, **kwargs): try: @@ -101,18 +102,43 @@ class ActivateAccountView(RedirectView): "Le lien de confirmation d'adresse mail ne correspond à aucun·e " "utilisateur·ice inscrit·e", ) - return reverse("home") + return reverse(self.failure_pattern_name) if not email_token_generator.check_token(user, token): messages.error( self.request, "Le lien de confirmation d'adresse mail est invalide ou déjà utilisé", ) - return reverse("home") + return reverse(self.failure_pattern_name) user.is_active = True user.email_confirmed = True user.save() login(self.request, user) - messages.info(self.request, "Votre adresse email a bien été confirmée.") - return reverse("home") + messages.success(self.request, "Votre adresse email a bien été confirmée.") + return reverse(self.success_pattern_name) + + +class UpdateAccountView(LoginRequiredMixin, UpdateView): + """Vue pour la mise à jour des infos personnelles""" + template_name = "update.html" + form_class = UpdateAccountForm + + def get_object(self): + return self.request.user + + # def get_context_data(self, **kwargs): + # context = super().get_context_data(**kwargs) + # context["change_password_form"] = registration_forms.UpdatePasswordForm( + # user=self.request.user + # ) + # return context + + def get_success_url(self): + # if not self.request.user.email_confirmed: + # return reverse("registration:email_confirmation_needed") + return reverse("accounts:profile") + + def form_valid(self, form): + messages.success(self.request, "Informations personnelles mises à jour") + return super().form_valid(form) -- GitLab