From f89d91e524dc033a355af5771e81512592e9c015 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 12:31:15 +0100 Subject: [PATCH 1/8] Format code --- apps/activity/admin.py | 2 +- apps/activity/api/serializers.py | 1 + apps/api/urls.py | 7 +- apps/member/admin.py | 4 +- apps/member/filters.py | 25 ++++--- apps/member/forms.py | 52 ++++++++------ apps/member/models.py | 12 ++-- apps/member/signals.py | 3 - apps/member/tables.py | 22 ++++-- apps/member/views.py | 99 ++++++++++++++++---------- apps/note/admin.py | 27 ++++--- apps/note/api/serializers.py | 6 +- apps/note/api/views.py | 19 +++-- apps/note/apps.py | 4 +- apps/note/forms.py | 69 +++++++++++------- apps/note/models/notes.py | 24 +++---- apps/note/tables.py | 13 ++-- apps/note/templatetags/pretty_money.py | 13 +++- apps/note/views.py | 27 ++++--- 19 files changed, 262 insertions(+), 167 deletions(-) diff --git a/apps/activity/admin.py b/apps/activity/admin.py index 1efe272c..494baffc 100644 --- a/apps/activity/admin.py +++ b/apps/activity/admin.py @@ -12,7 +12,7 @@ class ActivityAdmin(admin.ModelAdmin): Admin customisation for Activity """ list_display = ('name', 'activity_type', 'organizer') - list_filter = ('activity_type',) + list_filter = ('activity_type', ) search_fields = ['name', 'organizer__name'] # Organize activities by start date diff --git a/apps/activity/api/serializers.py b/apps/activity/api/serializers.py index f7f949e7..46bd8384 100644 --- a/apps/activity/api/serializers.py +++ b/apps/activity/api/serializers.py @@ -5,6 +5,7 @@ from ..models import ActivityType, Activity, Guest from rest_framework import serializers + class ActivityTypeSerializer(serializers.ModelSerializer): """ REST API Serializer for Activity types. diff --git a/apps/api/urls.py b/apps/api/urls.py index 7ac56ca1..475120fc 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -17,10 +17,13 @@ class UserSerializer(serializers.ModelSerializer): REST API Serializer for Users. The djangorestframework plugin will analyse the model `User` and parse all fields in the API. """ - class Meta: model = User - exclude = ('password', 'groups', 'user_permissions',) + exclude = ( + 'password', + 'groups', + 'user_permissions', + ) class UserViewSet(viewsets.ModelViewSet): diff --git a/apps/member/admin.py b/apps/member/admin.py index f45d5f55..2aa65d09 100644 --- a/apps/member/admin.py +++ b/apps/member/admin.py @@ -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): diff --git a/apps/member/filters.py b/apps/member/filters.py index fb1a2128..76e0d52b 100644 --- a/apps/member/filters.py +++ b/apps/member/filters.py @@ -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'), ) diff --git a/apps/member/forms.py b/apps/member/forms.py index 4d03764e..ef32e9b8 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -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", - ) - ) + )) diff --git a/apps/member/models.py b/apps/member/models.py index 35b7027c..ae5d90d5 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -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'), diff --git a/apps/member/signals.py b/apps/member/signals.py index 6688516b..6ac23376 100644 --- a/apps/member/signals.py +++ b/apps/member/signals.py @@ -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 - diff --git a/apps/member/tables.py b/apps/member/tables.py index 4218948c..8ae10476 100644 --- a/apps/member/tables.py +++ b/apps/member/tables.py @@ -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 diff --git a/apps/member/views.py b/apps/member/views.py index be2d8d58..86ce3b19 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -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) diff --git a/apps/note/admin.py b/apps/note/admin.py index 0b2461d0..be01da94 100644 --- a/apps/note/admin.py +++ b/apps/note/admin.py @@ -25,7 +25,10 @@ class NoteAdmin(PolymorphicParentModelAdmin): Parent regrouping all note types as children """ child_models = (NoteClub, NoteSpecial, NoteUser) - list_filter = (PolymorphicChildModelFilter, 'is_active',) + list_filter = ( + PolymorphicChildModelFilter, + 'is_active', + ) # Use a polymorphic list list_display = ('pretty', 'balance', 'is_active') @@ -44,11 +47,12 @@ class NoteClubAdmin(PolymorphicChildModelAdmin): """ Child for a club note, see NoteAdmin """ - inlines = (AliasInlines,) + inlines = (AliasInlines, ) # We can't change club after creation or the balance readonly_fields = ('club', 'balance') - search_fields = ('club',) + search_fields = ('club', ) + def has_add_permission(self, request): """ A club note should not be manually added @@ -67,7 +71,7 @@ class NoteSpecialAdmin(PolymorphicChildModelAdmin): """ Child for a special note, see NoteAdmin """ - readonly_fields = ('balance',) + readonly_fields = ('balance', ) @admin.register(NoteUser) @@ -75,7 +79,7 @@ class NoteUserAdmin(PolymorphicChildModelAdmin): """ Child for an user note, see NoteAdmin """ - inlines = (AliasInlines,) + inlines = (AliasInlines, ) # We can't change user after creation or the balance readonly_fields = ('user', 'balance') @@ -101,7 +105,10 @@ class TransactionAdmin(admin.ModelAdmin): list_display = ('created_at', 'poly_source', 'poly_destination', 'quantity', 'amount', 'transaction_type', 'valid') list_filter = ('transaction_type', 'valid') - autocomplete_fields = ('source', 'destination',) + autocomplete_fields = ( + 'source', + 'destination', + ) def poly_source(self, obj): """ @@ -136,8 +143,8 @@ class TransactionTemplateAdmin(admin.ModelAdmin): Admin customisation for TransactionTemplate """ list_display = ('name', 'poly_destination', 'amount', 'template_type') - list_filter = ('template_type',) - autocomplete_fields = ('destination',) + list_filter = ('template_type', ) + autocomplete_fields = ('destination', ) def poly_destination(self, obj): """ @@ -153,5 +160,5 @@ class TransactionCategoryAdmin(admin.ModelAdmin): """ Admin customisation for TransactionTemplate """ - list_display = ('name',) - list_filter = ('name',) + list_display = ('name', ) + list_filter = ('name', ) diff --git a/apps/note/api/serializers.py b/apps/note/api/serializers.py index afc3b419..90c802a9 100644 --- a/apps/note/api/serializers.py +++ b/apps/note/api/serializers.py @@ -17,7 +17,10 @@ class NoteSerializer(serializers.ModelSerializer): model = Note fields = '__all__' extra_kwargs = { - 'url': {'view_name': 'project-detail', 'lookup_field': 'pk'}, + 'url': { + 'view_name': 'project-detail', + 'lookup_field': 'pk' + }, } @@ -69,6 +72,7 @@ class NotePolymorphicSerializer(PolymorphicSerializer): NoteSpecial: NoteSpecialSerializer } + class TransactionTemplateSerializer(serializers.ModelSerializer): """ REST API Serializer for Transaction templates. diff --git a/apps/note/api/views.py b/apps/note/api/views.py index 37ca4e20..a63cf102 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -69,7 +69,9 @@ class NotePolymorphicViewSet(viewsets.ModelViewSet): queryset = Note.objects.all() alias = self.request.query_params.get("alias", ".*") - queryset = queryset.filter(Q(alias__name__regex=alias) | Q(alias__normalized_name__regex=alias.lower())) + queryset = queryset.filter( + Q(alias__name__regex=alias) + | Q(alias__normalized_name__regex=alias.lower())) note_type = self.request.query_params.get("type", None) if note_type: @@ -79,7 +81,8 @@ class NotePolymorphicViewSet(viewsets.ModelViewSet): elif "club" in l: queryset = queryset.filter(polymorphic_ctype__model="noteclub") elif "special" in l: - queryset = queryset.filter(polymorphic_ctype__model="notespecial") + queryset = queryset.filter( + polymorphic_ctype__model="notespecial") else: queryset = queryset.none() @@ -104,7 +107,8 @@ class AliasViewSet(viewsets.ModelViewSet): queryset = Alias.objects.all() alias = self.request.query_params.get("alias", ".*") - queryset = queryset.filter(Q(name__regex=alias) | Q(normalized_name__regex=alias.lower())) + queryset = queryset.filter( + Q(name__regex=alias) | Q(normalized_name__regex=alias.lower())) note_id = self.request.query_params.get("note", None) if note_id: @@ -114,11 +118,14 @@ class AliasViewSet(viewsets.ModelViewSet): if note_type: l = str(note_type).lower() if "user" in l: - queryset = queryset.filter(note__polymorphic_ctype__model="noteuser") + queryset = queryset.filter( + note__polymorphic_ctype__model="noteuser") elif "club" in l: - queryset = queryset.filter(note__polymorphic_ctype__model="noteclub") + queryset = queryset.filter( + note__polymorphic_ctype__model="noteclub") elif "special" in l: - queryset = queryset.filter(note__polymorphic_ctype__model="notespecial") + queryset = queryset.filter( + note__polymorphic_ctype__model="notespecial") else: queryset = queryset.none() diff --git a/apps/note/apps.py b/apps/note/apps.py index c53f915a..4ac2c847 100644 --- a/apps/note/apps.py +++ b/apps/note/apps.py @@ -20,9 +20,9 @@ class NoteConfig(AppConfig): """ post_save.connect( signals.save_user_note, - sender=settings.AUTH_USER_MODEL + sender=settings.AUTH_USER_MODEL, ) post_save.connect( signals.save_club_note, - sender='member.Club' + sender='member.Club', ) diff --git a/apps/note/forms.py b/apps/note/forms.py index 09818931..8f670455 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -4,10 +4,11 @@ from dal import autocomplete, forward from django import forms from .models import Transaction, TransactionTemplate + class TransactionTemplateForm(forms.ModelForm): class Meta: model = TransactionTemplate - fields ='__all__' + fields = '__all__' # Le champ de destination 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 @@ -15,11 +16,14 @@ class TransactionTemplateForm(forms.ModelForm): # Pour force le type d'une note, il faut rajouter le paramètre : # forward=(forward.Const('TYPE', 'note_type') où TYPE est dans {user, club, special} widgets = { - 'destination': autocomplete.ModelSelect2(url='note:note_autocomplete', - attrs={ - 'data-placeholder': 'Note ...', - 'data-minimum-input-length': 1, - }), + 'destination': + autocomplete.ModelSelect2( + url='note:note_autocomplete', + attrs={ + 'data-placeholder': 'Note ...', + 'data-minimum-input-length': 1, + }, + ), } @@ -31,26 +35,38 @@ class TransactionForm(forms.ModelForm): class Meta: model = Transaction - fields = ('source', 'destination', 'reason', 'amount',) + fields = ( + 'source', + 'destination', + 'reason', + 'amount', + ) # Voir ci-dessus widgets = { - 'source': autocomplete.ModelSelect2(url='note:note_autocomplete', - attrs={ - 'data-placeholder': 'Note ...', - 'data-minimum-input-length': 1, - },), - 'destination': autocomplete.ModelSelect2(url='note:note_autocomplete', - attrs={ - 'data-placeholder': 'Note ...', - 'data-minimum-input-length': 1, - },), + 'source': + autocomplete.ModelSelect2( + url='note:note_autocomplete', + attrs={ + 'data-placeholder': 'Note ...', + 'data-minimum-input-length': 1, + }, + ), + 'destination': + autocomplete.ModelSelect2( + url='note:note_autocomplete', + attrs={ + 'data-placeholder': 'Note ...', + 'data-minimum-input-length': 1, + }, + ), } -class ConsoForm(forms.ModelForm): +class ConsoForm(forms.ModelForm): def save(self, commit=True): - button: TransactionTemplate = TransactionTemplate.objects.filter(name=self.data['button']).get() + button: TransactionTemplate = TransactionTemplate.objects.filter( + name=self.data['button']).get() self.instance.destination = button.destination self.instance.amount = button.amount self.instance.transaction_type = 'bouton' @@ -59,15 +75,18 @@ class ConsoForm(forms.ModelForm): class Meta: model = Transaction - fields = ('source',) + fields = ('source', ) # 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 aliases de note valides widgets = { - 'source': autocomplete.ModelSelect2(url='note:note_autocomplete', - attrs={ - 'data-placeholder': 'Note ...', - 'data-minimum-input-length': 1, - }), + 'source': + autocomplete.ModelSelect2( + url='note:note_autocomplete', + attrs={ + 'data-placeholder': 'Note ...', + 'data-minimum-input-length': 1, + }, + ), } diff --git a/apps/note/models/notes.py b/apps/note/models/notes.py index 6a0c5ebe..a5ab993a 100644 --- a/apps/note/models/notes.py +++ b/apps/note/models/notes.py @@ -10,7 +10,6 @@ from django.core.validators import RegexValidator from django.db import models from django.utils.translation import gettext_lazy as _ from polymorphic.models import PolymorphicModel - """ Defines each note types """ @@ -34,8 +33,7 @@ class Note(PolymorphicModel): default=True, help_text=_( 'Designates whether this note should be treated as active. ' - 'Unselect this instead of deleting notes.' - ), + 'Unselect this instead of deleting notes.'), ) display_image = models.ImageField( verbose_name=_('display image'), @@ -85,7 +83,8 @@ class Note(PolymorphicModel): """ Verify alias (simulate save) """ - aliases = Alias.objects.filter(normalized_name=Alias.normalize(str(self))) + aliases = Alias.objects.filter( + normalized_name=Alias.normalize(str(self))) if aliases.exists(): # Alias exists, so check if it is linked to this note if aliases.first().note != self: @@ -181,15 +180,15 @@ class Alias(models.Model): validators=[ RegexValidator( regex=settings.ALIAS_VALIDATOR_REGEX, - message=_('Invalid alias') + message=_('Invalid alias'), ) - ] if settings.ALIAS_VALIDATOR_REGEX else [] + ] if settings.ALIAS_VALIDATOR_REGEX else [], ) normalized_name = models.CharField( max_length=255, unique=True, default='', - editable=False + editable=False, ) note = models.ForeignKey( Note, @@ -209,11 +208,9 @@ class Alias(models.Model): Normalizes a string: removes most diacritics and does casefolding """ return ''.join( - char - for char in unicodedata.normalize('NFKD', string.casefold()) + char for char in unicodedata.normalize('NFKD', string.casefold()) if all(not unicodedata.category(char).startswith(cat) - for cat in {'M', 'P', 'Z', 'C'}) - ).casefold() + for cat in {'M', 'P', 'Z', 'C'})).casefold() def save(self, *args, **kwargs): """ @@ -229,8 +226,9 @@ class Alias(models.Model): raise ValidationError(_('Alias too long.')) try: if self != Alias.objects.get(normalized_name=normalized_name): - raise ValidationError(_('An alias with a similar name ' - 'already exists.')) + raise ValidationError( + _('An alias with a similar name ' + 'already exists.')) except Alias.DoesNotExist: pass diff --git a/apps/note/tables.py b/apps/note/tables.py index 31cefe41..f13b502e 100644 --- a/apps/note/tables.py +++ b/apps/note/tables.py @@ -7,16 +7,19 @@ from .models.transactions import Transaction class HistoryTable(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 = Transaction template_name = 'django_tables2/bootstrap.html' - sequence = ('...','total','valid') + sequence = ('...', 'total', 'valid') - total = tables.Column() #will use Transaction.total() !! + total = tables.Column() #will use Transaction.total() !! def order_total(self, QuerySet, is_descending): # needed for rendering QuerySet = QuerySet.annotate( - total=F('amount') * F('quantity') - ).order_by(('-' if is_descending else '') + 'total') + total=F('amount') * + F('quantity')).order_by(('-' if is_descending else '') + 'total') return (QuerySet, True) diff --git a/apps/note/templatetags/pretty_money.py b/apps/note/templatetags/pretty_money.py index ec0a0d5b..c1525056 100644 --- a/apps/note/templatetags/pretty_money.py +++ b/apps/note/templatetags/pretty_money.py @@ -2,10 +2,17 @@ from django import template def pretty_money(value): - if value%100 == 0: - return "{:s}{:d} €".format("- " if value < 0 else "", abs(value) // 100) + if value % 100 == 0: + return "{:s}{:d} €".format( + "- " if value < 0 else "", + abs(value) // 100, + ) else: - return "{:s}{:d} € {:02d}".format("- " if value < 0 else "", abs(value) // 100, abs(value) % 100) + return "{:s}{:d} € {:02d}".format( + "- " if value < 0 else "", + abs(value) // 100, + abs(value) % 100, + ) register = template.Library() diff --git a/apps/note/views.py b/apps/note/views.py index 3414a6c0..d4590e5f 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -12,6 +12,7 @@ from django.views.generic import CreateView, ListView, DetailView, UpdateView from .models import Note, Transaction, TransactionCategory, TransactionTemplate, Alias from .forms import TransactionForm, TransactionTemplateForm, ConsoForm + class TransactionCreate(LoginRequiredMixin, CreateView): """ Show transfer page @@ -30,14 +31,13 @@ class TransactionCreate(LoginRequiredMixin, CreateView): 'to one or others') return context - def get_form(self, form_class=None): """ If the user has no right to transfer funds, then it won't have the choice of the source of the transfer. """ form = super().get_form(form_class) - if False: # TODO: fix it with "if %user has no right to transfer funds" + if False: # TODO: fix it with "if %user has no right to transfer funds" del form.fields['source'] return form @@ -46,7 +46,7 @@ class TransactionCreate(LoginRequiredMixin, CreateView): """ If the user has no right to transfer funds, then it will be the source of the transfer by default. """ - if False: # TODO: fix it with "if %user has no right to transfer funds" + if False: # TODO: fix it with "if %user has no right to transfer funds" form.instance.source = self.request.user.note return super().form_valid(form) @@ -56,7 +56,6 @@ class NoteAutocomplete(autocomplete.Select2QuerySetView): """ Auto complete note by aliases """ - def get_queryset(self): """ Quand une personne cherche un alias, une requête est envoyée sur l'API dédiée à l'auto-complétion. @@ -101,27 +100,30 @@ class NoteAutocomplete(autocomplete.Select2QuerySetView): return str(result.note.pk) -class TransactionTemplateCreateView(LoginRequiredMixin,CreateView): +class TransactionTemplateCreateView(LoginRequiredMixin, CreateView): """ Create TransactionTemplate """ model = TransactionTemplate form_class = TransactionTemplateForm -class TransactionTemplateListView(LoginRequiredMixin,ListView): + +class TransactionTemplateListView(LoginRequiredMixin, ListView): """ List TransactionsTemplates """ model = TransactionTemplate form_class = TransactionTemplateForm -class TransactionTemplateUpdateView(LoginRequiredMixin,UpdateView): + +class TransactionTemplateUpdateView(LoginRequiredMixin, UpdateView): """ """ model = TransactionTemplate form_class = TransactionTemplateForm -class ConsoView(LoginRequiredMixin,CreateView): + +class ConsoView(LoginRequiredMixin, CreateView): """ Consume """ @@ -139,11 +141,14 @@ class ConsoView(LoginRequiredMixin,CreateView): if 'template_type' not in self.kwargs.keys(): return context - template_type = TransactionCategory.objects.filter(name=self.kwargs.get('template_type')).get() - context['buttons'] = TransactionTemplate.objects.filter(template_type=template_type) + template_type = TransactionCategory.objects.filter( + name=self.kwargs.get('template_type')).get() + context['buttons'] = TransactionTemplate.objects.filter( + template_type=template_type) context['title'] = template_type return context def get_success_url(self): - return reverse('note:consos',args=(self.kwargs.get('template_type'),)) + return reverse('note:consos', + args=(self.kwargs.get('template_type'), )) From 62bfd9a044d84a704e3a499e66994f1d11a60633 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Tue, 18 Feb 2020 13:03:58 +0100 Subject: [PATCH 2/8] Remove redundant ; and import local settings --- note_kfet/settings/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/note_kfet/settings/__init__.py b/note_kfet/settings/__init__.py index 234e70b9..68a40b88 100644 --- a/note_kfet/settings/__init__.py +++ b/note_kfet/settings/__init__.py @@ -30,12 +30,17 @@ read_env() app_stage = os.environ.get('DJANGO_APP_STAGE', 'dev') if app_stage == 'prod': from .production import * - DATABASES["default"]["PASSWORD"] = os.environ.get('DJANGO_DB_PASSWORD','CHANGE_ME_IN_ENV_SETTINGS'); - SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY','CHANGE_ME_IN_ENV_SETTINGS'); - ALLOWED_HOSTS.append(os.environ.get('ALLOWED_HOSTS','localhost')); + DATABASES["default"]["PASSWORD"] = os.environ.get('DJANGO_DB_PASSWORD','CHANGE_ME_IN_ENV_SETTINGS') + SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY','CHANGE_ME_IN_ENV_SETTINGS') + ALLOWED_HOSTS.append(os.environ.get('ALLOWED_HOSTS','localhost')) else: from .development import * +try: + from .secrets import * +except ImportError: + pass + # env variables set at the of in /env/bin/activate # don't forget to unset in deactivate ! From ec3b445dcf8e612b5f9f4c6f26d85fd9afd15505 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 20:58:01 +0100 Subject: [PATCH 3/8] Code quality check with tox --- .gitlab-ci.yml | 15 +- .pylintrc | 379 ------------------------------------------------- tox.ini | 22 ++- 3 files changed, 20 insertions(+), 396 deletions(-) delete mode 100644 .pylintrc diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bceb5f51..291ed490 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,20 +2,25 @@ image: python:3.6 stages: - test + - quality-assurance before_script: - pip install tox -python36: +py36-django22: image: python:3.6 stage: test - script: tox -e py36 + script: tox -e py36-django22 -python37: +py37-django22: image: python:3.7 stage: test - script: tox -e py37 + script: tox -e py37-django22 linters: - stage: test + image: python:3.6 + stage: quality-assurance script: tox -e linters + + # Be nice to new contributors, but please use `tox` + allow_failure: true diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 6ddf1f3c..00000000 --- a/.pylintrc +++ /dev/null @@ -1,379 +0,0 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS,.git - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Use multiple processes to speed up Pylint. -jobs=4 - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Allow optimization of some AST trees. This will activate a peephole AST -# optimizer, which will apply various small optimizations. For instance, it can -# be used to obtain the result of joining multiple strings with the addition -# operator. Joining a lot of strings can lead to a maximum recursion error in -# Pylint and this flag can prevent that. It has one side effect, the resulting -# AST will be different than the one from reality. -optimize-ast=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence=INFERENCE_FAILURE - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. See also the "--disable" option for examples. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=intern-builtin,nonzero-method,parameter-unpacking,backtick,raw_input-builtin,dict-view-method,filter-builtin-not-iterating,long-builtin,unichr-builtin,input-builtin,unicode-builtin,file-builtin,map-builtin-not-iterating,delslice-method,apply-builtin,cmp-method,setslice-method,coerce-method,long-suffix,raising-string,import-star-module-level,buffer-builtin,reload-builtin,unpacking-in-except,print-statement,hex-method,old-octal-literal,metaclass-assignment,dict-iter-method,range-builtin-not-iterating,using-cmp-argument,indexing-exception,no-absolute-import,coerce-builtin,getslice-method,suppressed-message,execfile-builtin,round-builtin,useless-suppression,reduce-builtin,old-raise-syntax,zip-builtin-not-iterating,cmp-builtin,xrange-builtin,standarderror-builtin,old-division,oct-method,next-method-called,old-ne-operator,basestring-builtin - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -reports=no - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[BASIC] - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=yes - -# Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for argument names -argument-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for attribute names -attr-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for method names -method-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - - -[ELIF] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=100 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). This supports can work -# with qualified names. -ignored-classes= - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_$|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=20 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=20 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=10 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of boolean expressions in an if statement -max-bool-expr=5 - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=optparse - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception - diff --git a/tox.ini b/tox.ini index c8691372..c4e88c78 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,13 @@ [tox] -envlist = py36,py37,linters +envlist = + py36-django22 + py37-django22 + linters skipsdist = True [testenv] -basepython = python3 +setenv = + PYTHONWARNINGS = all deps = -r{toxinidir}/requirements.txt coverage @@ -12,11 +16,6 @@ commands = coverage run ./manage.py test {posargs} coverage report -m -[testenv:pre-commit] -deps = pre-commit -commands = - pre-commit run --all-files --show-diff-on-failure - [testenv:linters] deps = -r{toxinidir}/requirements.txt @@ -26,13 +25,12 @@ deps = flake8-typing-imports pep8-naming pyflakes - pylint commands = - flake8 app/activity app/member app/note - pylint . + flake8 apps/activity apps/api apps/member apps/note [flake8] -ignore = D203, W503, E203 +# Ignore too many errors, should be reduced in the future +ignore = D203, W503, E203, I100, I101 exclude = .tox, .git, @@ -45,7 +43,7 @@ exclude = .eggs, *migrations* max-complexity = 10 +max-line-length = 160 import-order-style = google application-import-names = flake8 format = ${cyan}%(path)s${reset}:${yellow_bold}%(row)d${reset}:${green_bold}%(col)d${reset}: ${red_bold}%(code)s${reset} %(text)s - From fb9af1c4c6d80ac98e486c91397048c1c96d4df3 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 20:58:45 +0100 Subject: [PATCH 4/8] Just target Django 2.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d103764e..2899ef61 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ certifi==2019.6.16 chardet==3.0.4 defusedxml==0.6.0 -Django==2.2.3 +Django~=2.2 django-allauth==0.39.1 django-autocomplete-light==3.3.0 django-crispy-forms==1.7.2 From cd98f96cd0bd4d7ae79a788f33c3aaa75df8914d Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 21:14:10 +0100 Subject: [PATCH 5/8] Ignore VSCode project settings --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f1650504..b57ed74a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,9 @@ coverage # PyCharm project settings .idea +# VSCode project settings +.vscode + # Local data secrets.py *.log From e679a4b6291a568679b05423493aae7a380b56de Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 21:14:29 +0100 Subject: [PATCH 6/8] Fix formatting issues --- apps/activity/api/serializers.py | 3 ++- apps/api/urls.py | 2 -- apps/member/api/serializers.py | 3 ++- apps/member/filters.py | 4 +--- apps/member/forms.py | 7 ++----- apps/member/models.py | 2 -- apps/member/tables.py | 4 ++-- apps/member/urls.py | 18 +++++++++--------- apps/member/views.py | 16 +++++++--------- apps/note/api/serializers.py | 5 +++-- apps/note/api/views.py | 16 ++++++++-------- apps/note/forms.py | 3 ++- apps/note/models/transactions.py | 14 +++++++------- apps/note/tables.py | 12 +++++------- apps/note/urls.py | 12 ++++++------ apps/note/views.py | 14 +++++++------- 16 files changed, 63 insertions(+), 72 deletions(-) diff --git a/apps/activity/api/serializers.py b/apps/activity/api/serializers.py index 46bd8384..b3c70338 100644 --- a/apps/activity/api/serializers.py +++ b/apps/activity/api/serializers.py @@ -2,9 +2,10 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from ..models import ActivityType, Activity, Guest from rest_framework import serializers +from ..models import ActivityType, Activity, Guest + class ActivityTypeSerializer(serializers.ModelSerializer): """ diff --git a/apps/api/urls.py b/apps/api/urls.py index 475120fc..4ff23e57 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -5,8 +5,6 @@ from django.conf.urls import url, include from django.contrib.auth.models import User from rest_framework import routers, serializers, viewsets -from rest_framework.authtoken import views as token_views - from activity.api.urls import register_activity_urls from member.api.urls import register_members_urls from note.api.urls import register_note_urls diff --git a/apps/member/api/serializers.py b/apps/member/api/serializers.py index cf4420d5..126d69b2 100644 --- a/apps/member/api/serializers.py +++ b/apps/member/api/serializers.py @@ -2,9 +2,10 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from ..models import Profile, Club, Role, Membership from rest_framework import serializers +from ..models import Profile, Club, Role, Membership + class ProfileSerializer(serializers.ModelSerializer): """ diff --git a/apps/member/filters.py b/apps/member/filters.py index 76e0d52b..ab63795a 100644 --- a/apps/member/filters.py +++ b/apps/member/filters.py @@ -2,14 +2,12 @@ # 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 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 - class UserFilter(FilterSet): class Meta: diff --git a/apps/member/forms.py b/apps/member/forms.py index ef32e9b8..3ea23762 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -2,17 +2,14 @@ # Copyright (C) 2018-2019 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from dal import autocomplete -from django.contrib.auth.forms import UserChangeForm, UserCreationForm +from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django import forms from .models import Profile, Club, Membership -from django.utils.translation import gettext_lazy as _ - from crispy_forms.helper import FormHelper -from crispy_forms import layout, bootstrap -from crispy_forms.bootstrap import InlineField, FormActions, StrictButton, Div, Field +from crispy_forms.bootstrap import Div from crispy_forms.layout import Layout diff --git a/apps/member/models.py b/apps/member/models.py index ae5d90d5..1009fe11 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -4,8 +4,6 @@ from django.conf import settings from django.db import models -from django.db.models.signals import post_save -from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ from django.urls import reverse, reverse_lazy diff --git a/apps/member/tables.py b/apps/member/tables.py index 8ae10476..e6417353 100644 --- a/apps/member/tables.py +++ b/apps/member/tables.py @@ -1,10 +1,10 @@ #!/usr/bin/env python import django_tables2 as tables -from .models import Club -from django.conf import settings from django.contrib.auth.models import User +from .models import Club + class ClubTable(tables.Table): class Meta: diff --git a/apps/member/urls.py b/apps/member/urls.py index d4e3e6af..d21c2a63 100644 --- a/apps/member/urls.py +++ b/apps/member/urls.py @@ -10,16 +10,16 @@ from . import views app_name = 'member' urlpatterns = [ - path('signup/',views.UserCreateView.as_view(),name="signup"), - path('club/',views.ClubListView.as_view(),name="club_list"), - path('club//',views.ClubDetailView.as_view(),name="club_detail"), - path('club//add_member/',views.ClubAddMemberView.as_view(),name="club_add_member"), - path('club/create/',views.ClubCreateView.as_view(),name="club_create"), - path('user/',views.UserListView.as_view(),name="user_list"), - path('user/',views.UserDetailView.as_view(),name="user_detail"), - path('user//update',views.UserUpdateView.as_view(),name="user_update_profile"), + path('signup/', views.UserCreateView.as_view(), name="signup"), + path('club/', views.ClubListView.as_view(), name="club_list"), + path('club//', views.ClubDetailView.as_view(), name="club_detail"), + path('club//add_member/', views.ClubAddMemberView.as_view(), name="club_add_member"), + path('club/create/', views.ClubCreateView.as_view(), name="club_create"), + path('user/', views.UserListView.as_view(), name="user_list"), + path('user/', views.UserDetailView.as_view(), name="user_detail"), + path('user//update', views.UserUpdateView.as_view(), name="user_update_profile"), path('manage-auth-token/', views.ManageAuthTokens.as_view(), name='auth_token'), # API for the user autocompleter - path('user/user-autocomplete',views.UserAutocomplete.as_view(),name="user_autocomplete"), + path('user/user-autocomplete', views.UserAutocomplete.as_view(), name="user_autocomplete"), ] diff --git a/apps/member/views.py b/apps/member/views.py index 86ce3b19..020b984a 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -6,23 +6,21 @@ from dal import autocomplete from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import redirect from django.utils.translation import gettext_lazy as _ -from django.views.generic import CreateView, ListView, DetailView, UpdateView, RedirectView, TemplateView +from django.views.generic import CreateView, DetailView, UpdateView, TemplateView from django.contrib.auth.models import User from django.urls import reverse_lazy from django.db.models import Q - from django_tables2.views import SingleTableView from rest_framework.authtoken.models import Token +from note.models import Alias, NoteUser +from note.models.transactions import Transaction +from note.tables import HistoryTable -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 .filters import UserFilter, UserFilterFormHelper -from note.models.transactions import Transaction -from note.tables import HistoryTable - class UserCreateView(CreateView): """ @@ -197,9 +195,9 @@ class UserAutocomplete(autocomplete.Select2QuerySetView): return qs -################################### -############## CLUB ############### -################################### +# ******************************* # +# CLUB # +# ******************************* # class ClubCreateView(LoginRequiredMixin, CreateView): diff --git a/apps/note/api/serializers.py b/apps/note/api/serializers.py index 90c802a9..a0b92725 100644 --- a/apps/note/api/serializers.py +++ b/apps/note/api/serializers.py @@ -2,11 +2,12 @@ # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later -from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias -from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction from rest_framework import serializers from rest_polymorphic.serializers import PolymorphicSerializer +from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias +from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction + class NoteSerializer(serializers.ModelSerializer): """ diff --git a/apps/note/api/views.py b/apps/note/api/views.py index a63cf102..1d015125 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -75,12 +75,12 @@ class NotePolymorphicViewSet(viewsets.ModelViewSet): note_type = self.request.query_params.get("type", None) if note_type: - l = str(note_type).lower() - if "user" in l: + types = str(note_type).lower() + if "user" in types: queryset = queryset.filter(polymorphic_ctype__model="noteuser") - elif "club" in l: + elif "club" in types: queryset = queryset.filter(polymorphic_ctype__model="noteclub") - elif "special" in l: + elif "special" in types: queryset = queryset.filter( polymorphic_ctype__model="notespecial") else: @@ -116,14 +116,14 @@ class AliasViewSet(viewsets.ModelViewSet): note_type = self.request.query_params.get("type", None) if note_type: - l = str(note_type).lower() - if "user" in l: + types = str(note_type).lower() + if "user" in types: queryset = queryset.filter( note__polymorphic_ctype__model="noteuser") - elif "club" in l: + elif "club" in types: queryset = queryset.filter( note__polymorphic_ctype__model="noteclub") - elif "special" in l: + elif "special" in types: queryset = queryset.filter( note__polymorphic_ctype__model="notespecial") else: diff --git a/apps/note/forms.py b/apps/note/forms.py index 8f670455..225afb91 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -1,7 +1,8 @@ #!/usr/bin/env python -from dal import autocomplete, forward +from dal import autocomplete from django import forms + from .models import Transaction, TransactionTemplate diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py index 5c242255..95940b65 100644 --- a/apps/note/models/transactions.py +++ b/apps/note/models/transactions.py @@ -7,12 +7,13 @@ from django.utils import timezone from django.utils.translation import gettext_lazy as _ from django.urls import reverse -from .notes import Note,NoteClub +from .notes import Note, NoteClub """ Defines transactions """ + class TransactionCategory(models.Model): """ Defined a recurrent transaction category @@ -32,6 +33,7 @@ class TransactionCategory(models.Model): def __str__(self): return str(self.name) + class TransactionTemplate(models.Model): """ Defined a recurrent transaction @@ -57,7 +59,7 @@ class TransactionTemplate(models.Model): TransactionCategory, on_delete=models.PROTECT, verbose_name=_('type'), - max_length=31 + max_length=31, ) class Meta: @@ -65,7 +67,7 @@ class TransactionTemplate(models.Model): verbose_name_plural = _("transaction templates") def get_absolute_url(self): - return reverse('note:template_update',args=(self.pk,)) + return reverse('note:template_update', args=(self.pk, )) class Transaction(models.Model): @@ -98,9 +100,7 @@ class Transaction(models.Model): verbose_name=_('quantity'), default=1, ) - amount = models.PositiveIntegerField( - verbose_name=_('amount'), - ) + amount = models.PositiveIntegerField(verbose_name=_('amount'), ) transaction_type = models.CharField( verbose_name=_('type'), max_length=31, @@ -142,7 +142,7 @@ class Transaction(models.Model): @property def total(self): - return self.amount*self.quantity + return self.amount * self.quantity class MembershipTransaction(Transaction): diff --git a/apps/note/tables.py b/apps/note/tables.py index f13b502e..4a52dd13 100644 --- a/apps/note/tables.py +++ b/apps/note/tables.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python import django_tables2 as tables from django.db.models import F @@ -15,11 +14,10 @@ class HistoryTable(tables.Table): template_name = 'django_tables2/bootstrap.html' sequence = ('...', 'total', 'valid') - total = tables.Column() #will use Transaction.total() !! + total = tables.Column() # will use Transaction.total() !! - def order_total(self, QuerySet, is_descending): + def order_total(self, queryset, is_descending): # needed for rendering - QuerySet = QuerySet.annotate( - total=F('amount') * - F('quantity')).order_by(('-' if is_descending else '') + 'total') - return (QuerySet, True) + queryset = queryset.annotate(total=F('amount') * F('quantity')) \ + .order_by(('-' if is_descending else '') + 'total') + return (queryset, True) diff --git a/apps/note/urls.py b/apps/note/urls.py index 7c19c425..6567cb95 100644 --- a/apps/note/urls.py +++ b/apps/note/urls.py @@ -10,12 +10,12 @@ from .models import Note app_name = 'note' urlpatterns = [ path('transfer/', views.TransactionCreate.as_view(), name='transfer'), - path('buttons/create/',views.TransactionTemplateCreateView.as_view(),name='template_create'), - path('buttons/update//',views.TransactionTemplateUpdateView.as_view(),name='template_update'), - path('buttons/',views.TransactionTemplateListView.as_view(),name='template_list'), - path('consos//',views.ConsoView.as_view(),name='consos'), - path('consos/',views.ConsoView.as_view(),name='consos'), + path('buttons/create/', views.TransactionTemplateCreateView.as_view(), name='template_create'), + path('buttons/update//', views.TransactionTemplateUpdateView.as_view(), name='template_update'), + path('buttons/', views.TransactionTemplateListView.as_view(), name='template_list'), + path('consos//', views.ConsoView.as_view(), name='consos'), + path('consos/', views.ConsoView.as_view(), name='consos'), # API for the note autocompleter - path('note-autocomplete/', views.NoteAutocomplete.as_view(model=Note),name='note_autocomplete'), + path('note-autocomplete/', views.NoteAutocomplete.as_view(model=Note), name='note_autocomplete'), ] diff --git a/apps/note/views.py b/apps/note/views.py index d4590e5f..e7776687 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -5,11 +5,11 @@ from dal import autocomplete from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Q -from django.urls import reverse_lazy, reverse +from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from django.views.generic import CreateView, ListView, DetailView, UpdateView +from django.views.generic import CreateView, ListView, UpdateView -from .models import Note, Transaction, TransactionCategory, TransactionTemplate, Alias +from .models import Transaction, TransactionCategory, TransactionTemplate, Alias from .forms import TransactionForm, TransactionTemplateForm, ConsoForm @@ -75,12 +75,12 @@ class NoteAutocomplete(autocomplete.Select2QuerySetView): # Filtrage par type de note (user, club, special) note_type = self.forwarded.get("note_type", None) if note_type: - l = str(note_type).lower() - if "user" in l: + types = str(note_type).lower() + if "user" in types: qs = qs.filter(note__polymorphic_ctype__model="noteuser") - elif "club" in l: + elif "club" in types: qs = qs.filter(note__polymorphic_ctype__model="noteclub") - elif "special" in l: + elif "special" in types: qs = qs.filter(note__polymorphic_ctype__model="notespecial") else: qs = qs.none() From 4bbd464f9ceeb7a5cf2d0ba668cee6089e53d840 Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 21:30:26 +0100 Subject: [PATCH 7/8] Unify file headers --- apps/activity/__init__.py | 3 +-- apps/activity/admin.py | 3 +-- apps/activity/api/serializers.py | 1 - apps/activity/api/urls.py | 1 - apps/activity/api/views.py | 1 - apps/activity/apps.py | 3 +-- apps/activity/models.py | 3 +-- apps/api/urls.py | 1 - apps/member/__init__.py | 3 +-- apps/member/admin.py | 3 +-- apps/member/api/serializers.py | 1 - apps/member/api/urls.py | 1 - apps/member/api/views.py | 1 - apps/member/apps.py | 3 +-- apps/member/filters.py | 3 +-- apps/member/forms.py | 4 ++-- apps/member/models.py | 3 +-- apps/member/signals.py | 3 +-- apps/member/tables.py | 3 ++- apps/member/urls.py | 5 +---- apps/member/views.py | 5 ++--- apps/note/__init__.py | 3 +-- apps/note/admin.py | 3 +-- apps/note/api/serializers.py | 1 - apps/note/api/urls.py | 1 - apps/note/api/views.py | 1 - apps/note/apps.py | 3 +-- apps/note/forms.py | 3 ++- apps/note/models/__init__.py | 3 +-- apps/note/models/notes.py | 3 +-- apps/note/models/transactions.py | 3 +-- apps/note/signals.py | 3 +-- apps/note/tables.py | 3 +++ apps/note/templatetags/pretty_money.py | 3 +++ apps/note/urls.py | 3 +-- apps/note/views.py | 3 +-- entrypoint.sh | 5 +++++ note_kfet/settings/base.py | 3 +-- note_kfet/settings/development.py | 3 +++ note_kfet/settings/production.py | 3 +++ note_kfet/urls.py | 3 +-- note_kfet/wsgi.py | 1 - 42 files changed, 47 insertions(+), 64 deletions(-) diff --git a/apps/activity/__init__.py b/apps/activity/__init__.py index 75df9e1f..195d5302 100644 --- a/apps/activity/__init__.py +++ b/apps/activity/__init__.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later default_app_config = 'activity.apps.ActivityConfig' diff --git a/apps/activity/admin.py b/apps/activity/admin.py index 494baffc..5ceb4e81 100644 --- a/apps/activity/admin.py +++ b/apps/activity/admin.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.contrib import admin diff --git a/apps/activity/api/serializers.py b/apps/activity/api/serializers.py index b3c70338..0b9302f1 100644 --- a/apps/activity/api/serializers.py +++ b/apps/activity/api/serializers.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/activity/api/urls.py b/apps/activity/api/urls.py index 56665730..79e0ba30 100644 --- a/apps/activity/api/urls.py +++ b/apps/activity/api/urls.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/activity/api/views.py b/apps/activity/api/views.py index 4a0973e5..5683d458 100644 --- a/apps/activity/api/views.py +++ b/apps/activity/api/views.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/activity/apps.py b/apps/activity/apps.py index 29990f1b..bb72947f 100644 --- a/apps/activity/apps.py +++ b/apps/activity/apps.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.apps import AppConfig diff --git a/apps/activity/models.py b/apps/activity/models.py index 4dbc5522..8f23060c 100644 --- a/apps/activity/models.py +++ b/apps/activity/models.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.conf import settings diff --git a/apps/api/urls.py b/apps/api/urls.py index 4ff23e57..7e59a8c0 100644 --- a/apps/api/urls.py +++ b/apps/api/urls.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/member/__init__.py b/apps/member/__init__.py index ec189d6f..298d1dda 100644 --- a/apps/member/__init__.py +++ b/apps/member/__init__.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later default_app_config = 'member.apps.MemberConfig' diff --git a/apps/member/admin.py b/apps/member/admin.py index 2aa65d09..fb107377 100644 --- a/apps/member/admin.py +++ b/apps/member/admin.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.contrib import admin diff --git a/apps/member/api/serializers.py b/apps/member/api/serializers.py index 126d69b2..f4df6799 100644 --- a/apps/member/api/serializers.py +++ b/apps/member/api/serializers.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/member/api/urls.py b/apps/member/api/urls.py index f60465c0..15bb83ca 100644 --- a/apps/member/api/urls.py +++ b/apps/member/api/urls.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/member/api/views.py b/apps/member/api/views.py index 36e8a33f..79ba4c12 100644 --- a/apps/member/api/views.py +++ b/apps/member/api/views.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/member/apps.py b/apps/member/apps.py index 928c00e4..2d7f4ab7 100644 --- a/apps/member/apps.py +++ b/apps/member/apps.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.apps import AppConfig diff --git a/apps/member/filters.py b/apps/member/filters.py index ab63795a..418e52fc 100644 --- a/apps/member/filters.py +++ b/apps/member/filters.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django_filters import FilterSet, CharFilter diff --git a/apps/member/forms.py b/apps/member/forms.py index 3ea23762..66844cf4 100644 --- a/apps/member/forms.py +++ b/apps/member/forms.py @@ -1,6 +1,6 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later + from dal import autocomplete from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User diff --git a/apps/member/models.py b/apps/member/models.py index 1009fe11..cd754bd8 100644 --- a/apps/member/models.py +++ b/apps/member/models.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.conf import settings diff --git a/apps/member/signals.py b/apps/member/signals.py index 6ac23376..4e945ad5 100644 --- a/apps/member/signals.py +++ b/apps/member/signals.py @@ -1,3 +1,2 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/member/tables.py b/apps/member/tables.py index e6417353..591149ec 100644 --- a/apps/member/tables.py +++ b/apps/member/tables.py @@ -1,4 +1,5 @@ -#!/usr/bin/env python +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later import django_tables2 as tables from django.contrib.auth.models import User diff --git a/apps/member/urls.py b/apps/member/urls.py index d21c2a63..6a7ed5ce 100644 --- a/apps/member/urls.py +++ b/apps/member/urls.py @@ -1,7 +1,4 @@ -#!/usr/bin/env python - -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.urls import path diff --git a/apps/member/views.py b/apps/member/views.py index 020b984a..c1231fbc 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -1,7 +1,6 @@ -#!/usr/bin/env python - -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later + from dal import autocomplete from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import redirect diff --git a/apps/note/__init__.py b/apps/note/__init__.py index 4773b310..f7c331b2 100644 --- a/apps/note/__init__.py +++ b/apps/note/__init__.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later default_app_config = 'note.apps.NoteConfig' diff --git a/apps/note/admin.py b/apps/note/admin.py index be01da94..3a9721ae 100644 --- a/apps/note/admin.py +++ b/apps/note/admin.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.contrib import admin diff --git a/apps/note/api/serializers.py b/apps/note/api/serializers.py index a0b92725..db0e3531 100644 --- a/apps/note/api/serializers.py +++ b/apps/note/api/serializers.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/note/api/urls.py b/apps/note/api/urls.py index 4ef14e28..54218796 100644 --- a/apps/note/api/urls.py +++ b/apps/note/api/urls.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/note/api/views.py b/apps/note/api/views.py index 1d015125..94b4a47a 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/note/apps.py b/apps/note/apps.py index 4ac2c847..4881e3b9 100644 --- a/apps/note/apps.py +++ b/apps/note/apps.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.apps import AppConfig diff --git a/apps/note/forms.py b/apps/note/forms.py index 225afb91..e4fd344c 100644 --- a/apps/note/forms.py +++ b/apps/note/forms.py @@ -1,4 +1,5 @@ -#!/usr/bin/env python +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later from dal import autocomplete from django import forms diff --git a/apps/note/models/__init__.py b/apps/note/models/__init__.py index ee290bb5..7e6cc310 100644 --- a/apps/note/models/__init__.py +++ b/apps/note/models/__init__.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from .notes import Alias, Note, NoteClub, NoteSpecial, NoteUser diff --git a/apps/note/models/notes.py b/apps/note/models/notes.py index a5ab993a..3b616f0e 100644 --- a/apps/note/models/notes.py +++ b/apps/note/models/notes.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later import unicodedata diff --git a/apps/note/models/transactions.py b/apps/note/models/transactions.py index 95940b65..042faa16 100644 --- a/apps/note/models/transactions.py +++ b/apps/note/models/transactions.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.db import models diff --git a/apps/note/signals.py b/apps/note/signals.py index 6e5d5c9e..ad376ee0 100644 --- a/apps/note/signals.py +++ b/apps/note/signals.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/apps/note/tables.py b/apps/note/tables.py index 4a52dd13..e2f5c763 100644 --- a/apps/note/tables.py +++ b/apps/note/tables.py @@ -1,3 +1,6 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + import django_tables2 as tables from django.db.models import F diff --git a/apps/note/templatetags/pretty_money.py b/apps/note/templatetags/pretty_money.py index c1525056..12530c6e 100644 --- a/apps/note/templatetags/pretty_money.py +++ b/apps/note/templatetags/pretty_money.py @@ -1,3 +1,6 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + from django import template diff --git a/apps/note/urls.py b/apps/note/urls.py index 6567cb95..e1cc5216 100644 --- a/apps/note/urls.py +++ b/apps/note/urls.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.urls import path diff --git a/apps/note/views.py b/apps/note/views.py index e7776687..b012ad8b 100644 --- a/apps/note/views.py +++ b/apps/note/views.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from dal import autocomplete diff --git a/entrypoint.sh b/entrypoint.sh index da32571a..f05e962a 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,11 @@ #!/bin/bash +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + python manage.py compilemessages python manage.py makemigrations + +# Wait for database sleep 5 python manage.py migrate diff --git a/note_kfet/settings/base.py b/note_kfet/settings/base.py index 9a526863..410f496f 100644 --- a/note_kfet/settings/base.py +++ b/note_kfet/settings/base.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later import os diff --git a/note_kfet/settings/development.py b/note_kfet/settings/development.py index f6d48776..60055ee2 100644 --- a/note_kfet/settings/development.py +++ b/note_kfet/settings/development.py @@ -1,3 +1,6 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + ######################## # Development Settings # ######################## diff --git a/note_kfet/settings/production.py b/note_kfet/settings/production.py index 02c46ed2..296c17a4 100644 --- a/note_kfet/settings/production.py +++ b/note_kfet/settings/production.py @@ -1,3 +1,6 @@ +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay +# SPDX-License-Identifier: GPL-3.0-or-later + ######################## # Production Settings # ######################## diff --git a/note_kfet/urls.py b/note_kfet/urls.py index 9fd63eef..303e229a 100644 --- a/note_kfet/urls.py +++ b/note_kfet/urls.py @@ -1,5 +1,4 @@ -# -*- mode: python; coding: utf-8 -*- -# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay +# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later from django.contrib import admin diff --git a/note_kfet/wsgi.py b/note_kfet/wsgi.py index 94a8e054..b89430ec 100644 --- a/note_kfet/wsgi.py +++ b/note_kfet/wsgi.py @@ -1,4 +1,3 @@ -# -*- mode: python; coding: utf-8 -*- # Copyright (C) 2016-2019 by BDE # SPDX-License-Identifier: GPL-3.0-or-later From 204fe53047e1b2165b7ec888f87fe6e09cb5629d Mon Sep 17 00:00:00 2001 From: Alexandre Iooss Date: Tue, 18 Feb 2020 21:47:03 +0100 Subject: [PATCH 8/8] Remove broken code --- apps/member/views.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/member/views.py b/apps/member/views.py index c1231fbc..366523b0 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -247,11 +247,13 @@ class ClubAddMemberView(LoginRequiredMixin, CreateView): return context 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) + return + # TODO: Implement POST + # formset = MembershipFormset(request.POST) + # if formset.is_valid(): + # return self.form_valid(formset) + # else: + # return self.form_invalid(formset) def form_valid(self, formset): formset.save()