mirror of
https://gitlab.com/animath/si/plateforme-corres2math.git
synced 2025-06-21 23:58:21 +02:00
Personal page
This commit is contained in:
@ -26,6 +26,18 @@ class SignupForm(UserCreationForm):
|
||||
fields = ('first_name', 'last_name', 'email', 'password1', 'password2', 'role',)
|
||||
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields["first_name"].required = True
|
||||
self.fields["last_name"].required = True
|
||||
self.fields["email"].required = True
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name', 'email',)
|
||||
|
||||
|
||||
class StudentRegistrationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = StudentRegistration
|
||||
|
@ -50,6 +50,10 @@ class Registration(PolymorphicModel):
|
||||
def type(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def form_class(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def participates(self):
|
||||
return isinstance(self, StudentRegistration) or isinstance(self, CoachRegistration)
|
||||
@ -90,6 +94,11 @@ class StudentRegistration(Registration):
|
||||
def type(self):
|
||||
return _("student")
|
||||
|
||||
@property
|
||||
def form_class(self):
|
||||
from registration.forms import StudentRegistrationForm
|
||||
return StudentRegistrationForm
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("student registration")
|
||||
verbose_name_plural = _("student registrations")
|
||||
@ -113,6 +122,11 @@ class CoachRegistration(Registration):
|
||||
def type(self):
|
||||
return _("coach")
|
||||
|
||||
@property
|
||||
def form_class(self):
|
||||
from registration.forms import CoachRegistrationForm
|
||||
return CoachRegistrationForm
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("coach registration")
|
||||
verbose_name_plural = _("coach registrations")
|
||||
@ -127,6 +141,11 @@ class AdminRegistration(Registration):
|
||||
def type(self):
|
||||
return _("admin")
|
||||
|
||||
@property
|
||||
def form_class(self):
|
||||
from registration.forms import AdminRegistrationForm
|
||||
return AdminRegistrationForm
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("admin registration")
|
||||
verbose_name_plural = _("admin registrations")
|
||||
|
15
apps/registration/templates/registration/update_user.html
Normal file
15
apps/registration/templates/registration/update_user.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load crispy_forms_filters i18n %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post">
|
||||
<div id="form-content">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
{{ registration_form|crispy }}
|
||||
</div>
|
||||
<button class="btn btn-success" type="submit">{% trans "Update" %}</button>
|
||||
</form>
|
||||
{% endblock content %}
|
||||
|
@ -0,0 +1,21 @@
|
||||
{% load i18n %}
|
||||
|
||||
<div id="updateUserModal" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form method="post" action="{% url "registration:update_user" pk=user.pk %}">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{% trans "Update user" %}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">{% trans "Update" %}</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{% trans "Close" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
59
apps/registration/templates/registration/user_detail.html
Normal file
59
apps/registration/templates/registration/user_detail.html
Normal file
@ -0,0 +1,59 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
{% trans "any" as any %}
|
||||
|
||||
<div class="card bg-light shadow">
|
||||
<div class="card-header text-center">
|
||||
<h4>{{ user.first_name }} {{ user.last_name }}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<dl class="row">
|
||||
<dt class="col-sm-6 text-right">{% trans "Last name:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.last_name }}</dd>
|
||||
|
||||
<dt class="col-sm-6 text-right">{% trans "First name:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.first_name }}</dd>
|
||||
|
||||
<dt class="col-sm-6 text-right">{% trans "Email:" %}</dt>
|
||||
<dd class="col-sm-6"><a href="mailto:{{ user.email }}">{{ user.email }}</a></dd>
|
||||
|
||||
{% if user.registration.studentregistration %}
|
||||
<dt class="col-sm-6 text-right">{% trans "Student class:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.registration.get_student_class_display }}</dd>
|
||||
|
||||
<dt class="col-sm-6 text-right">{% trans "School:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.registration.school }}</dd>
|
||||
{% elif user.registration.coachregistration %}
|
||||
<dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.registration.professional_activity }}</dd>
|
||||
{% elif user.registration.adminregistration %}
|
||||
<dt class="col-sm-6 text-right">{% trans "Role:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.registration.role }}</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt class="col-sm-6 text-right">{% trans "Grant Animath to contact me in the future about other actions:" %}</dt>
|
||||
<dd class="col-sm-6">{{ user.registration.give_contact_to_animath|yesno }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<button class="btn btn-primary" data-toggle="modal" data-target="#updateUserModal">{% trans "Update" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include "registration/update_user_modal.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrajavascript %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('button[data-target="#updateUserModal"]').click(function() {
|
||||
let modalBody = $("#updateUserModal div.modal-body");
|
||||
if (!modalBody.html().trim())
|
||||
modalBody.load("{% url "registration:update_user" pk=user.pk %} #form-content");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
@ -23,6 +23,11 @@ class TestRegistration(TestCase):
|
||||
)
|
||||
self.client.force_login(self.user)
|
||||
|
||||
self.student = User.objects.create(email="student@example.com")
|
||||
StudentRegistration.objects.create(user=self.student, student_class=11, school="Earth")
|
||||
self.coach = User.objects.create(email="coach@example.com")
|
||||
CoachRegistration.objects.create(user=self.coach, professional_activity="Teacher")
|
||||
|
||||
def test_registration(self):
|
||||
response = self.client.get(reverse("registration:signup"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@ -105,15 +110,46 @@ class TestRegistration(TestCase):
|
||||
))
|
||||
self.assertRedirects(response, reverse("index"), 302, 200)
|
||||
|
||||
def test_change_email(self):
|
||||
self.user.email = "newaddressmail@example.com"
|
||||
self.user.save()
|
||||
self.assertEqual(self.user.email, self.user.username)
|
||||
def test_user_detail(self):
|
||||
response = self.client.get(reverse("registration:my_account_detail"))
|
||||
self.assertRedirects(response, reverse("registration:user_detail", args=(self.user.pk,)))
|
||||
|
||||
response = self.client.get(reverse("registration:user_detail", args=(self.user.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_update_user(self):
|
||||
for user, data in [(self.user, dict(role="Bot")),
|
||||
(self.student, dict(student_class=11, school="Sky")),
|
||||
(self.coach, dict(professional_activity="God"))]:
|
||||
response = self.client.get(reverse("registration:update_user", args=(user.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(reverse("registration:update_user", args=(user.pk,)), data=dict(
|
||||
first_name="Changed",
|
||||
last_name="Name",
|
||||
email="new_" + user.email,
|
||||
give_contact_to_animath=True,
|
||||
))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
data.update(
|
||||
first_name="Changed",
|
||||
last_name="Name",
|
||||
email="new_" + user.email,
|
||||
give_contact_to_animath=True,
|
||||
)
|
||||
response = self.client.post(reverse("registration:update_user", args=(user.pk,)), data=data)
|
||||
self.assertRedirects(response, reverse("registration:user_detail", args=(user.pk,)), 302, 200)
|
||||
user.refresh_from_db()
|
||||
self.assertEqual(user.email, user.username)
|
||||
self.assertFalse(user.registration.email_confirmed)
|
||||
self.assertEqual(user.first_name, "Changed")
|
||||
|
||||
def test_string_render(self):
|
||||
# TODO These string field tests will be removed when used in a template
|
||||
str(self.user.registration)
|
||||
self.assertRaises(NotImplementedError, lambda: Registration().type)
|
||||
self.assertRaises(NotImplementedError, lambda: Registration().form_class)
|
||||
str(StudentRegistration().type)
|
||||
str(CoachRegistration().type)
|
||||
str(self.user.registration.type) # AdminRegistration
|
||||
|
@ -1,6 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import SignupView, UserResendValidationEmailView, UserValidateView, UserValidationEmailSentView
|
||||
from .views import MyAccountDetailView, SignupView, UserDetailView, UserResendValidationEmailView, UserUpdateView,\
|
||||
UserValidateView, UserValidationEmailSentView
|
||||
|
||||
app_name = "registration"
|
||||
|
||||
@ -10,4 +11,7 @@ urlpatterns = [
|
||||
path('validate_email/resend/<int:pk>/', UserResendValidationEmailView.as_view(),
|
||||
name='email_validation_resend'),
|
||||
path('validate_email/<uidb64>/<token>/', UserValidateView.as_view(), name='email_validation'),
|
||||
path("user/", MyAccountDetailView.as_view(), name="my_account_detail"),
|
||||
path("user/<int:pk>/", UserDetailView.as_view(), name="user_detail"),
|
||||
path("user/<int:pk>/update/", UserUpdateView.as_view(), name="update_user"),
|
||||
]
|
||||
|
@ -8,9 +8,9 @@ from django.shortcuts import redirect, resolve_url
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.http import urlsafe_base64_decode
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import CreateView, DetailView, TemplateView
|
||||
from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView
|
||||
|
||||
from .forms import CoachRegistrationForm, SignupForm, StudentRegistrationForm
|
||||
from .forms import CoachRegistrationForm, SignupForm, StudentRegistrationForm, UserForm
|
||||
|
||||
|
||||
class SignupView(CreateView):
|
||||
@ -118,3 +118,40 @@ class UserResendValidationEmailView(LoginRequiredMixin, DetailView):
|
||||
user = self.get_object()
|
||||
user.registration.send_email_validation_link()
|
||||
return redirect('registration:email_validation_sent')
|
||||
|
||||
|
||||
class MyAccountDetailView(LoginRequiredMixin, RedirectView):
|
||||
def get_redirect_url(self, *args, **kwargs):
|
||||
return reverse_lazy("registration:user_detail", args=(self.request.user.pk,))
|
||||
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
model = User
|
||||
template_name = "registration/user_detail.html"
|
||||
|
||||
|
||||
class UserUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = User
|
||||
form_class = UserForm
|
||||
template_name = "registration/update_user.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
user = self.get_object()
|
||||
context["registration_form"] = user.registration.form_class(data=self.request.POST or None,
|
||||
instance=self.object.registration)
|
||||
return context
|
||||
|
||||
@transaction.atomic
|
||||
def form_valid(self, form):
|
||||
user = form.instance
|
||||
registration_form = user.registration.form_class(data=self.request.POST or None,
|
||||
instance=self.object.registration)
|
||||
if not registration_form.is_valid():
|
||||
return self.form_invalid(form)
|
||||
|
||||
registration_form.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse_lazy("registration:user_detail", args=(self.object.pk,))
|
||||
|
Reference in New Issue
Block a user