Generic registration view
This commit is contained in:
parent
f93a68b942
commit
0f491ef396
6 changed files with 200 additions and 19 deletions
|
@ -1,12 +0,0 @@
|
||||||
{% extends "base_title.html" %}
|
|
||||||
|
|
||||||
{% block realcontent %}
|
|
||||||
<h2>Inscription d'un nouveau membre</h2>
|
|
||||||
{% if success %}
|
|
||||||
<p class="success">L'inscription de {{ member.first_name }} {{ member.last_name }} (<tt>{{ member.username }}</tt>) a été enregistrée avec succès.
|
|
||||||
{% if member.profile.is_cof %}Il est désormais membre du COF n°{{ member.profile.num }} !{% endif %}</p>
|
|
||||||
{% endif %}
|
|
||||||
<div id="form-placeholder">
|
|
||||||
{% include "cof/registration_form.html" %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
|
@ -4,6 +4,10 @@ from django.contrib.auth.models import User
|
||||||
from .models import Profile
|
from .models import Profile
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Profile edition
|
||||||
|
# ---
|
||||||
|
|
||||||
class UserForm(forms.ModelForm):
|
class UserForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
|
@ -14,3 +18,48 @@ class ProfileForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Profile
|
model = Profile
|
||||||
fields = ["phone", "departement"]
|
fields = ["phone", "departement"]
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Registration
|
||||||
|
# ---
|
||||||
|
|
||||||
|
class UserRegistrationForm(forms.ModelForm):
|
||||||
|
passwd1 = forms.CharField(
|
||||||
|
label="Mot de passe",
|
||||||
|
widget=forms.PasswordInput,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
passwd2 = forms.CharField(
|
||||||
|
label="Confirmation de mot de passe",
|
||||||
|
widget=forms.PasswordInput,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean_passwd2(self):
|
||||||
|
passwd1 = self.cleaned_data["passwd1"]
|
||||||
|
passwd2 = self.cleaned_data["passwd2"]
|
||||||
|
if passwd1 and passwd2:
|
||||||
|
if passwd1 != passwd2:
|
||||||
|
raise forms.ValidationError("Mots de passes différents")
|
||||||
|
return passwd2
|
||||||
|
|
||||||
|
def save(self, commit=True, *args, **kwargs):
|
||||||
|
user = super().save(commit, *args, **kwargs)
|
||||||
|
if self.cleaned_data["passwd2"]:
|
||||||
|
user.set_password(self.cleaned_data["passwd2"])
|
||||||
|
if commit:
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ["username", "first_name", "last_name", "email"]
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileRegistrationForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = Profile
|
||||||
|
fields = [
|
||||||
|
"login_clipper", "phone", "occupation", "departement", "comments"
|
||||||
|
]
|
||||||
|
|
|
@ -3,6 +3,21 @@ Locking/unlocking tools to prevent tables to be corrupted
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def get_or_create_clipper(clipper, fullname=None):
|
||||||
|
user, created = User.objects.get_or_create(username=clipper)
|
||||||
|
if created:
|
||||||
|
user.email = settings.CAS_EMAIL_FORMAT % (clipper, )
|
||||||
|
if fullname:
|
||||||
|
bits = fullname.split(" ")
|
||||||
|
user.first_name = bits[0]
|
||||||
|
if len(bits) > 1:
|
||||||
|
user.last_name = " ".join(bits[1:])
|
||||||
|
user.save()
|
||||||
|
return (user, created)
|
||||||
|
|
||||||
|
|
||||||
def lock_table(*models):
|
def lock_table(*models):
|
||||||
|
|
|
@ -4,14 +4,18 @@
|
||||||
{% block page_size %}col-sm-8{% endblock %}
|
{% block page_size %}col-sm-8{% endblock %}
|
||||||
|
|
||||||
{% block extra_head %}
|
{% block extra_head %}
|
||||||
<script src="{% static "autocomplete_light/autocomplete.js" %}" type="text/javascript"></script>
|
<script src="{% static "autocomplete_light/autocomplete.js" %}" type="text/javascript"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block realcontent %}
|
{% block realcontent %}
|
||||||
<h2>Inscription d'un nouveau membre</h2>
|
<h2>Inscription d'un nouveau membre</h2>
|
||||||
|
|
||||||
<input type="text" name="q" id="search_autocomplete" spellcheck="false" />
|
<input type="text" name="q" id="search_autocomplete" spellcheck="false" />
|
||||||
<div id="form-placeholder"></div>
|
<div id="form-placeholder">
|
||||||
|
{% if user %}{% include "gestion/registration_form.html" %}{% endif %}
|
||||||
|
</div>
|
||||||
<div class="yourlabs-autocomplete"></div>
|
<div class="yourlabs-autocomplete"></div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// On attend que la page soit prête pour executer le code
|
// On attend que la page soit prête pour executer le code
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
|
@ -7,7 +7,7 @@
|
||||||
{% else %}
|
{% else %}
|
||||||
<h3>Inscription d'un nouveau compte (extérieur ?)</h3>
|
<h3>Inscription d'un nouveau compte (extérieur ?)</h3>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form role="form" id="profile" method="post" action="{% url 'registration' %}">
|
<form role="form" id="profile" method="post" action="{{ page_url }}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<table>
|
<table>
|
||||||
{{ user_form | bootstrap }}
|
{{ user_form | bootstrap }}
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</table>
|
</table>
|
||||||
<hr />
|
<hr />
|
||||||
<table>
|
<table>
|
||||||
{{ cofprofile_form | bootstrap }}
|
{{ extra_form | bootstrap }}
|
||||||
</table>
|
</table>
|
||||||
{{ event_formset.management_form }}
|
{{ event_formset.management_form }}
|
||||||
{% for event_form in event_formset %}
|
{% for event_form in event_formset %}
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
{{ event_form | bootstrap }}
|
{{ event_form | bootstrap }}
|
||||||
</table>
|
</table>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if login_clipper or member %}
|
{% if user %}
|
||||||
<input type="hidden" name="user_exists" value="1" />
|
<input type="hidden" name="user_exists" value="1" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<input type="submit" class="btn btn-primary pull-right" value="Enregistrer l'inscription" />
|
<input type="submit" class="btn btn-primary pull-right" value="Enregistrer l'inscription" />
|
129
gestion/views.py
129
gestion/views.py
|
@ -4,16 +4,27 @@ The common views of the different organisations.
|
||||||
- Profile edition
|
- Profile edition
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.shortcuts import render, redirect
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.views import (
|
from django.contrib.auth.views import (
|
||||||
login as django_login, logout as django_logout
|
login as django_login, logout as django_logout
|
||||||
)
|
)
|
||||||
|
from django.http import HttpResponseBadRequest
|
||||||
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
from .forms import ProfileForm, UserForm
|
from .forms import (
|
||||||
|
ProfileForm, UserForm, UserRegistrationForm, ProfileRegistrationForm
|
||||||
|
)
|
||||||
|
from .shared import get_or_create_clipper
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Authentcation
|
||||||
|
# ---
|
||||||
|
|
||||||
def login(request):
|
def login(request):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
return redirect("home")
|
return redirect("home")
|
||||||
|
@ -54,6 +65,10 @@ def logout(request):
|
||||||
return django_logout(request)
|
return django_logout(request)
|
||||||
|
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# User management
|
||||||
|
# ---
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def profile(request):
|
def profile(request):
|
||||||
success = False
|
success = False
|
||||||
|
@ -71,3 +86,113 @@ def profile(request):
|
||||||
return render(request, "gestion/profile.html",
|
return render(request, "gestion/profile.html",
|
||||||
{"user_form": user_form, "profile_form": profile_form,
|
{"user_form": user_form, "profile_form": profile_form,
|
||||||
"success": success})
|
"success": success})
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: send "Welcome" email
|
||||||
|
class RegistrationView(TemplateView):
|
||||||
|
user = None
|
||||||
|
form_class = None
|
||||||
|
form_only = False # TODO: explain this
|
||||||
|
page_url = "" # TODO: explain this
|
||||||
|
|
||||||
|
def get_form_kwargs(self, **kwargs):
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Template related code
|
||||||
|
# ---
|
||||||
|
|
||||||
|
@property
|
||||||
|
def template_name(self):
|
||||||
|
if self.form_only:
|
||||||
|
return "gestion/registration_form.html"
|
||||||
|
else:
|
||||||
|
return "gestion/registration.html"
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
post_data = kwargs.pop("post_data", None)
|
||||||
|
user = self.user
|
||||||
|
context["user"] = user
|
||||||
|
context["page_url"] = self.page_url
|
||||||
|
context["user_form"] = UserRegistrationForm(
|
||||||
|
instance=user,
|
||||||
|
prefix="user",
|
||||||
|
data=post_data
|
||||||
|
)
|
||||||
|
context["profile_form"] = ProfileRegistrationForm(
|
||||||
|
instance=user.profile if user else None,
|
||||||
|
prefix="profile",
|
||||||
|
data=post_data
|
||||||
|
)
|
||||||
|
context["extra_form"] = self.form_class(**self.get_form_kwargs(
|
||||||
|
prefix="extra",
|
||||||
|
data=post_data,
|
||||||
|
))
|
||||||
|
return context
|
||||||
|
|
||||||
|
# ---
|
||||||
|
# Request processing
|
||||||
|
# ---
|
||||||
|
|
||||||
|
def get(self, request, username=""):
|
||||||
|
"""
|
||||||
|
The `user_type` GET parameter is used the following way:
|
||||||
|
- If not set, return empty forms.
|
||||||
|
- If set to "normal", assume the user exists.
|
||||||
|
- If set to, "clipper" create a user linked to a clipper account if a
|
||||||
|
user with the provided username doesn't exist.
|
||||||
|
|
||||||
|
The `fullname` GET parameter is only used to create new clipper users
|
||||||
|
"""
|
||||||
|
user_type, fullname = self.clean_GET(request.GET)
|
||||||
|
if user_type == "clipper":
|
||||||
|
self.user, _ = get_or_create_clipper(username, fullname)
|
||||||
|
elif user_type == "normal":
|
||||||
|
self.user = get_object_or_404(User, username=username)
|
||||||
|
|
||||||
|
context = self.get_context_data()
|
||||||
|
print(vars(self))
|
||||||
|
return super().render_to_response(context)
|
||||||
|
|
||||||
|
# def post(self, request, username):
|
||||||
|
def post(self, request):
|
||||||
|
# the `user_exists` POST parameter indicates that we should expect the
|
||||||
|
# user to be in the database already. Otherwise we return a 404 page.
|
||||||
|
# TODO: 404 is bad, prefer an "displayable" error
|
||||||
|
if "user_exists" in request.POST:
|
||||||
|
username = request.POST.get("user-username", "")
|
||||||
|
self.user = get_object_or_404(User, username=username)
|
||||||
|
context = self.get_context_data(
|
||||||
|
post_data=request.POST,
|
||||||
|
)
|
||||||
|
if all([context["user_form"].is_valid(),
|
||||||
|
context["profile_form"].is_valid(),
|
||||||
|
context["extra_form"].is_valid()]):
|
||||||
|
self.user = context["user_form"].save()
|
||||||
|
context["user"] = self.user
|
||||||
|
context["profile_form"].save()
|
||||||
|
context["extra_form"].save()
|
||||||
|
messages.success(
|
||||||
|
request,
|
||||||
|
_("L'inscription de %(fullname)s (<tt>%(username)s</tt>)"
|
||||||
|
" a été enregistrée avec succès")
|
||||||
|
% {"fullname": self.user.get_full_name(),
|
||||||
|
"username": self.user.username}
|
||||||
|
)
|
||||||
|
return super().render_to_response(context)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def clean_GET(get_params):
|
||||||
|
allowed_user_types = {"normal", "clipper", None}
|
||||||
|
user_type = get_params.get("user_type")
|
||||||
|
if user_type not in allowed_user_types:
|
||||||
|
return HttpResponseBadRequest(
|
||||||
|
"Invalid value `{}` expected `({})`"
|
||||||
|
.format(user_type, "|".join(allowed_user_types))
|
||||||
|
)
|
||||||
|
fullname = get_params.get("fullname")
|
||||||
|
if fullname is not None:
|
||||||
|
fullname = str(fullname)
|
||||||
|
return user_type, fullname
|
||||||
|
|
Loading…
Reference in a new issue