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
|
||||
|
||||
|
||||
# ---
|
||||
# Profile edition
|
||||
# ---
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
|
@ -14,3 +18,48 @@ class ProfileForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Profile
|
||||
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.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):
|
||||
|
|
|
@ -4,14 +4,18 @@
|
|||
{% block page_size %}col-sm-8{% endblock %}
|
||||
|
||||
{% 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 %}
|
||||
|
||||
{% block realcontent %}
|
||||
<h2>Inscription d'un nouveau membre</h2>
|
||||
|
||||
<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>
|
||||
|
||||
<script type="text/javascript">
|
||||
// On attend que la page soit prête pour executer le code
|
||||
$(document).ready(function() {
|
|
@ -7,7 +7,7 @@
|
|||
{% else %}
|
||||
<h3>Inscription d'un nouveau compte (extérieur ?)</h3>
|
||||
{% endif %}
|
||||
<form role="form" id="profile" method="post" action="{% url 'registration' %}">
|
||||
<form role="form" id="profile" method="post" action="{{ page_url }}">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ user_form | bootstrap }}
|
||||
|
@ -15,7 +15,7 @@
|
|||
</table>
|
||||
<hr />
|
||||
<table>
|
||||
{{ cofprofile_form | bootstrap }}
|
||||
{{ extra_form | bootstrap }}
|
||||
</table>
|
||||
{{ event_formset.management_form }}
|
||||
{% for event_form in event_formset %}
|
||||
|
@ -25,7 +25,7 @@
|
|||
{{ event_form | bootstrap }}
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% if login_clipper or member %}
|
||||
{% if user %}
|
||||
<input type="hidden" name="user_exists" value="1" />
|
||||
{% endif %}
|
||||
<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
|
||||
"""
|
||||
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.views import (
|
||||
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):
|
||||
if request.user.is_authenticated():
|
||||
return redirect("home")
|
||||
|
@ -54,6 +65,10 @@ def logout(request):
|
|||
return django_logout(request)
|
||||
|
||||
|
||||
# ---
|
||||
# User management
|
||||
# ---
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
success = False
|
||||
|
@ -71,3 +86,113 @@ def profile(request):
|
|||
return render(request, "gestion/profile.html",
|
||||
{"user_form": user_form, "profile_form": profile_form,
|
||||
"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