mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-21 09:58:23 +02:00
Format code
This commit is contained in:
@ -19,9 +19,9 @@ class ProfileInline(admin.StackedInline):
|
||||
|
||||
|
||||
class CustomUserAdmin(UserAdmin):
|
||||
inlines = (ProfileInline,)
|
||||
inlines = (ProfileInline, )
|
||||
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
|
||||
list_select_related = ('profile',)
|
||||
list_select_related = ('profile', )
|
||||
form = ProfileForm
|
||||
|
||||
def get_inline_instances(self, request, obj=None):
|
||||
|
@ -2,30 +2,35 @@
|
||||
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from django_filters import FilterSet, CharFilter,NumberFilter
|
||||
from django_filters import FilterSet, CharFilter, NumberFilter
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models import CharField
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Submit
|
||||
|
||||
from .models import Club
|
||||
from .models import Club
|
||||
|
||||
|
||||
class UserFilter(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['last_name','first_name','username','profile__section']
|
||||
filter_overrides={
|
||||
CharField:{
|
||||
'filter_class':CharFilter,
|
||||
'extra': lambda f:{
|
||||
'lookup_expr':'icontains'
|
||||
fields = ['last_name', 'first_name', 'username', 'profile__section']
|
||||
filter_overrides = {
|
||||
CharField: {
|
||||
'filter_class': CharFilter,
|
||||
'extra': lambda f: {
|
||||
'lookup_expr': 'icontains'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UserFilterFormHelper(FormHelper):
|
||||
form_method = 'GET'
|
||||
layout = Layout(
|
||||
'last_name','first_name','username','profile__section',
|
||||
Submit('Submit','Apply Filter'),
|
||||
'last_name',
|
||||
'first_name',
|
||||
'username',
|
||||
'profile__section',
|
||||
Submit('Submit', 'Apply Filter'),
|
||||
)
|
||||
|
@ -16,11 +16,11 @@ from crispy_forms.bootstrap import InlineField, FormActions, StrictButton, Div,
|
||||
from crispy_forms.layout import Layout
|
||||
|
||||
|
||||
|
||||
class SignUpForm(UserCreationForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['first_name','last_name','username','email']
|
||||
fields = ['first_name', 'last_name', 'username', 'email']
|
||||
|
||||
|
||||
class ProfileForm(forms.ModelForm):
|
||||
"""
|
||||
@ -31,48 +31,56 @@ class ProfileForm(forms.ModelForm):
|
||||
fields = '__all__'
|
||||
exclude = ['user']
|
||||
|
||||
|
||||
class ClubForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Club
|
||||
fields ='__all__'
|
||||
fields = '__all__'
|
||||
|
||||
|
||||
class AddMembersForm(forms.Form):
|
||||
class Meta:
|
||||
fields = ('',)
|
||||
fields = ('', )
|
||||
|
||||
|
||||
class MembershipForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Membership
|
||||
fields = ('user','roles','date_start')
|
||||
fields = ('user', 'roles', 'date_start')
|
||||
# Le champ d'utilisateur est remplacé par un champ d'auto-complétion.
|
||||
# Quand des lettres sont tapées, une requête est envoyée sur l'API d'auto-complétion
|
||||
# et récupère les noms d'utilisateur valides
|
||||
widgets = {
|
||||
'user': autocomplete.ModelSelect2(url='member:user_autocomplete',
|
||||
attrs={
|
||||
'data-placeholder': 'Nom ...',
|
||||
'data-minimum-input-length': 1,
|
||||
}),
|
||||
'user':
|
||||
autocomplete.ModelSelect2(
|
||||
url='member:user_autocomplete',
|
||||
attrs={
|
||||
'data-placeholder': 'Nom ...',
|
||||
'data-minimum-input-length': 1,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
MemberFormSet = forms.modelformset_factory(Membership,
|
||||
form=MembershipForm,
|
||||
extra=2,
|
||||
can_delete=True)
|
||||
MemberFormSet = forms.modelformset_factory(
|
||||
Membership,
|
||||
form=MembershipForm,
|
||||
extra=2,
|
||||
can_delete=True,
|
||||
)
|
||||
|
||||
|
||||
class FormSetHelper(FormHelper):
|
||||
def __init__(self,*args,**kwargs):
|
||||
super().__init__(*args,**kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.form_tag = False
|
||||
self.form_method = 'POST'
|
||||
self.form_class='form-inline'
|
||||
self.form_class = 'form-inline'
|
||||
# self.template = 'bootstrap/table_inline_formset.html'
|
||||
self.layout = Layout(
|
||||
Div(
|
||||
Div('user',css_class='col-sm-2'),
|
||||
Div('roles',css_class='col-sm-2'),
|
||||
Div('date_start',css_class='col-sm-2'),
|
||||
Div('user', css_class='col-sm-2'),
|
||||
Div('roles', css_class='col-sm-2'),
|
||||
Div('date_start', css_class='col-sm-2'),
|
||||
css_class="row formset-row",
|
||||
)
|
||||
)
|
||||
))
|
||||
|
@ -9,6 +9,7 @@ from django.dispatch import receiver
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.urls import reverse, reverse_lazy
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
"""
|
||||
An user profile
|
||||
@ -50,7 +51,8 @@ class Profile(models.Model):
|
||||
verbose_name_plural = _('user profile')
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('user_detail',args=(self.pk,))
|
||||
return reverse('user_detail', args=(self.pk, ))
|
||||
|
||||
|
||||
class Club(models.Model):
|
||||
"""
|
||||
@ -98,7 +100,7 @@ class Club(models.Model):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse_lazy('member:club_detail', args=(self.pk,))
|
||||
return reverse_lazy('member:club_detail', args=(self.pk, ))
|
||||
|
||||
|
||||
class Role(models.Model):
|
||||
@ -129,15 +131,15 @@ class Membership(models.Model):
|
||||
"""
|
||||
user = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.PROTECT
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
club = models.ForeignKey(
|
||||
Club,
|
||||
on_delete=models.PROTECT
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
roles = models.ForeignKey(
|
||||
Role,
|
||||
on_delete=models.PROTECT
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
date_start = models.DateField(
|
||||
verbose_name=_('membership starts on'),
|
||||
|
@ -1,6 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# -*- mode: python; coding: utf-8 -*-
|
||||
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
@ -5,15 +5,20 @@ from .models import Club
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
class ClubTable(tables.Table):
|
||||
class Meta:
|
||||
attrs = {'class':'table table-bordered table-condensed table-striped table-hover'}
|
||||
attrs = {
|
||||
'class':
|
||||
'table table-bordered table-condensed table-striped table-hover'
|
||||
}
|
||||
model = Club
|
||||
template_name = 'django_tables2/bootstrap.html'
|
||||
fields = ('id','name','email')
|
||||
row_attrs = {'class':'table-row',
|
||||
'data-href': lambda record: record.pk }
|
||||
|
||||
fields = ('id', 'name', 'email')
|
||||
row_attrs = {
|
||||
'class': 'table-row',
|
||||
'data-href': lambda record: record.pk
|
||||
}
|
||||
|
||||
|
||||
class UserTable(tables.Table):
|
||||
@ -21,7 +26,10 @@ class UserTable(tables.Table):
|
||||
solde = tables.Column(accessor='note.balance')
|
||||
|
||||
class Meta:
|
||||
attrs = {'class':'table table-bordered table-condensed table-striped table-hover'}
|
||||
attrs = {
|
||||
'class':
|
||||
'table table-bordered table-condensed table-striped table-hover'
|
||||
}
|
||||
template_name = 'django_tables2/bootstrap.html'
|
||||
fields = ('last_name','first_name','username','email')
|
||||
fields = ('last_name', 'first_name', 'username', 'email')
|
||||
model = User
|
||||
|
@ -16,14 +16,14 @@ from rest_framework.authtoken.models import Token
|
||||
|
||||
from note.models import Alias, Note, NoteUser
|
||||
from .models import Profile, Club, Membership
|
||||
from .forms import SignUpForm, ProfileForm, ClubForm,MembershipForm, MemberFormSet,FormSetHelper
|
||||
from .tables import ClubTable,UserTable
|
||||
from .forms import SignUpForm, ProfileForm, ClubForm, MembershipForm, MemberFormSet, FormSetHelper
|
||||
from .tables import ClubTable, UserTable
|
||||
from .filters import UserFilter, UserFilterFormHelper
|
||||
|
||||
|
||||
from note.models.transactions import Transaction
|
||||
from note.tables import HistoryTable
|
||||
|
||||
|
||||
class UserCreateView(CreateView):
|
||||
"""
|
||||
Une vue pour inscrire un utilisateur et lui créer un profile
|
||||
@ -31,10 +31,10 @@ class UserCreateView(CreateView):
|
||||
|
||||
form_class = SignUpForm
|
||||
success_url = reverse_lazy('login')
|
||||
template_name ='member/signup.html'
|
||||
template_name = 'member/signup.html'
|
||||
second_form = ProfileForm
|
||||
|
||||
def get_context_data(self,**kwargs):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["profile_form"] = self.second_form()
|
||||
|
||||
@ -49,17 +49,20 @@ class UserCreateView(CreateView):
|
||||
profile.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
class UserUpdateView(LoginRequiredMixin,UpdateView):
|
||||
|
||||
class UserUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = User
|
||||
fields = ['first_name','last_name','username','email']
|
||||
fields = ['first_name', 'last_name', 'username', 'email']
|
||||
template_name = 'member/profile_update.html'
|
||||
|
||||
second_form = ProfileForm
|
||||
def get_context_data(self,**kwargs):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['user_modified'] = context['user']
|
||||
context['user'] = self.request.user
|
||||
context["profile_form"] = self.second_form(instance=context['user_modified'].profile)
|
||||
context["profile_form"] = self.second_form(
|
||||
instance=context['user_modified'].profile)
|
||||
|
||||
return context
|
||||
|
||||
@ -71,44 +74,52 @@ class UserUpdateView(LoginRequiredMixin,UpdateView):
|
||||
new_username = form.data['username']
|
||||
|
||||
# Si l'utilisateur cherche à modifier son pseudo, le nouveau pseudo ne doit pas être proche d'un alias existant
|
||||
note = NoteUser.objects.filter(alias__normalized_name=Alias.normalize(new_username))
|
||||
note = NoteUser.objects.filter(
|
||||
alias__normalized_name=Alias.normalize(new_username))
|
||||
if note.exists() and note.get().user != self.request.user:
|
||||
form.add_error('username', _("An alias with a similar name already exists."))
|
||||
form.add_error('username',
|
||||
_("An alias with a similar name already exists."))
|
||||
|
||||
return form
|
||||
|
||||
|
||||
def form_valid(self, form):
|
||||
profile_form = ProfileForm(data=self.request.POST,instance=self.request.user.profile)
|
||||
profile_form = ProfileForm(
|
||||
data=self.request.POST,
|
||||
instance=self.request.user.profile,
|
||||
)
|
||||
if form.is_valid() and profile_form.is_valid():
|
||||
new_username = form.data['username']
|
||||
alias = Alias.objects.filter(name=new_username)
|
||||
# Si le nouveau pseudo n'est pas un de nos alias, on supprime éventuellement un alias similaire pour le remplacer
|
||||
if not alias.exists():
|
||||
similar = Alias.objects.filter(normalized_name=Alias.normalize(new_username))
|
||||
similar = Alias.objects.filter(
|
||||
normalized_name=Alias.normalize(new_username))
|
||||
if similar.exists():
|
||||
similar.delete()
|
||||
|
||||
user = form.save(commit=False)
|
||||
profile = profile_form.save(commit=False)
|
||||
profile = profile_form.save(commit=False)
|
||||
profile.user = user
|
||||
profile.save()
|
||||
user.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self, **kwargs):
|
||||
if kwargs:
|
||||
return reverse_lazy('member:user_detail', kwargs = {'pk': kwargs['id']})
|
||||
if kwargs:
|
||||
return reverse_lazy('member:user_detail',
|
||||
kwargs={'pk': kwargs['id']})
|
||||
else:
|
||||
return reverse_lazy('member:user_detail', args = (self.object.id,))
|
||||
return reverse_lazy('member:user_detail', args=(self.object.id, ))
|
||||
|
||||
class UserDetailView(LoginRequiredMixin,DetailView):
|
||||
|
||||
class UserDetailView(LoginRequiredMixin, DetailView):
|
||||
"""
|
||||
Affiche les informations sur un utilisateur, sa note, ses clubs ...
|
||||
"""
|
||||
model = Profile
|
||||
context_object_name = "profile"
|
||||
def get_context_data(slef,**kwargs):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
user = context['profile'].user
|
||||
history_list = \
|
||||
@ -119,7 +130,8 @@ class UserDetailView(LoginRequiredMixin,DetailView):
|
||||
context['club_list'] = ClubTable(club_list)
|
||||
return context
|
||||
|
||||
class UserListView(LoginRequiredMixin,SingleTableView):
|
||||
|
||||
class UserListView(LoginRequiredMixin, SingleTableView):
|
||||
"""
|
||||
Affiche la liste des utilisateurs, avec une fonction de recherche statique
|
||||
"""
|
||||
@ -129,13 +141,13 @@ class UserListView(LoginRequiredMixin,SingleTableView):
|
||||
filter_class = UserFilter
|
||||
formhelper_class = UserFilterFormHelper
|
||||
|
||||
def get_queryset(self,**kwargs):
|
||||
def get_queryset(self, **kwargs):
|
||||
qs = super().get_queryset()
|
||||
self.filter = self.filter_class(self.request.GET,queryset=qs)
|
||||
self.filter = self.filter_class(self.request.GET, queryset=qs)
|
||||
self.filter.form.helper = self.formhelper_class()
|
||||
return self.filter.qs
|
||||
|
||||
def get_context_data(self,**kwargs):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["filter"] = self.filter
|
||||
return context
|
||||
@ -149,22 +161,25 @@ class ManageAuthTokens(LoginRequiredMixin, TemplateView):
|
||||
template_name = "member/manage_auth_tokens.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if 'regenerate' in request.GET and Token.objects.filter(user=request.user).exists():
|
||||
if 'regenerate' in request.GET and Token.objects.filter(
|
||||
user=request.user).exists():
|
||||
Token.objects.get(user=self.request.user).delete()
|
||||
return redirect(reverse_lazy('member:auth_token') + "?show", permanent=True)
|
||||
return redirect(reverse_lazy('member:auth_token') + "?show",
|
||||
permanent=True)
|
||||
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['token'] = Token.objects.get_or_create(user=self.request.user)[0]
|
||||
context['token'] = Token.objects.get_or_create(
|
||||
user=self.request.user)[0]
|
||||
return context
|
||||
|
||||
|
||||
class UserAutocomplete(autocomplete.Select2QuerySetView):
|
||||
"""
|
||||
Auto complete users by usernames
|
||||
"""
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
Quand une personne cherche un utilisateur par pseudo, une requête est envoyée sur l'API dédiée à l'auto-complétion.
|
||||
@ -181,32 +196,36 @@ class UserAutocomplete(autocomplete.Select2QuerySetView):
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
###################################
|
||||
############## CLUB ###############
|
||||
###################################
|
||||
|
||||
class ClubCreateView(LoginRequiredMixin,CreateView):
|
||||
|
||||
class ClubCreateView(LoginRequiredMixin, CreateView):
|
||||
"""
|
||||
Create Club
|
||||
"""
|
||||
model = Club
|
||||
form_class = ClubForm
|
||||
|
||||
def form_valid(self,form):
|
||||
def form_valid(self, form):
|
||||
return super().form_valid(form)
|
||||
|
||||
class ClubListView(LoginRequiredMixin,SingleTableView):
|
||||
|
||||
class ClubListView(LoginRequiredMixin, SingleTableView):
|
||||
"""
|
||||
List existing Clubs
|
||||
"""
|
||||
model = Club
|
||||
table_class = ClubTable
|
||||
|
||||
class ClubDetailView(LoginRequiredMixin,DetailView):
|
||||
model = Club
|
||||
context_object_name="club"
|
||||
|
||||
def get_context_data(self,**kwargs):
|
||||
class ClubDetailView(LoginRequiredMixin, DetailView):
|
||||
model = Club
|
||||
context_object_name = "club"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
club = context["club"]
|
||||
club_transactions = \
|
||||
@ -218,23 +237,25 @@ class ClubDetailView(LoginRequiredMixin,DetailView):
|
||||
context['member_list'] = club_member
|
||||
return context
|
||||
|
||||
class ClubAddMemberView(LoginRequiredMixin,CreateView):
|
||||
|
||||
class ClubAddMemberView(LoginRequiredMixin, CreateView):
|
||||
model = Membership
|
||||
form_class = MembershipForm
|
||||
template_name = 'member/add_members.html'
|
||||
def get_context_data(self,**kwargs):
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['formset'] = MemberFormSet()
|
||||
context['helper'] = FormSetHelper()
|
||||
return context
|
||||
|
||||
def post(self,request,*args,**kwargs):
|
||||
def post(self, request, *args, **kwargs):
|
||||
formset = MembershipFormset(request.POST)
|
||||
if formset.is_valid():
|
||||
return self.form_valid(formset)
|
||||
else:
|
||||
return self.form_invalid(formset)
|
||||
|
||||
def form_valid(self,formset):
|
||||
def form_valid(self, formset):
|
||||
formset.save()
|
||||
return super().form_valid(formset)
|
||||
|
Reference in New Issue
Block a user