From b0b0542407384fe7988162119228edf286eecb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delobelle?= Date: Sun, 19 Nov 2017 18:41:39 +0100 Subject: [PATCH] Upgrade to Django 1.11 - Deprecation warnings using Django 1.8 are resolved. - Deprecation warnings using Django 1.11 are resolved. - Admin: grappelli is no longer used. - Upgrade to django-autocomplete-light v3 (v2 is not 1.11 compatible). * autocomplete.modelform_factory being dropped, code uses dal Select2 views and widgets. --- bda/admin.py | 15 +++- bda/autocomplete_light_registry.py | 18 ----- bda/migrations/0001_initial.py | 12 +-- bda/migrations/0002_add_tirage.py | 10 +-- bda/migrations/0007_extends_spectacle.py | 4 +- bda/migrations/0009_revente.py | 3 + bda/models.py | 50 ++++++++---- bda/urls.py | 6 ++ bda/views.py | 25 ++++++ cof/settings/common.py | 17 ++-- cof/settings/dev.py | 11 +-- cof/urls.py | 25 +++--- gestioncof/admin.py | 12 ++- gestioncof/autocomplete_light_registry.py | 10 --- gestioncof/migrations/0001_initial.py | 40 +++++----- gestioncof/migrations/0006_add_calendar.py | 3 +- gestioncof/models.py | 51 ++++++++---- gestioncof/petits_cours_models.py | 31 ++++++-- gestioncof/petits_cours_views.py | 4 +- gestioncof/templates/admin/base_site.html | 6 -- gestioncof/templates/admin/index.html | 78 ------------------- .../templates/gestioncof/base_header.html | 4 +- gestioncof/templates/gestioncof/event.html | 2 +- gestioncof/templates/home.html | 20 ++--- gestioncof/templates/login.html | 2 +- gestioncof/templates/login_switch.html | 4 +- .../registration/password_change_done.html | 2 +- .../registration/password_change_form.html | 2 +- gestioncof/urls.py | 18 +++-- gestioncof/views.py | 21 ++++- kfet/auth/middleware.py | 9 ++- kfet/auth/tests.py | 8 +- kfet/cms/migrations/0001_initial.py | 2 +- kfet/models.py | 2 +- kfet/templates/kfet/base_nav.html | 10 ++- kfet/tests/test_views.py | 2 +- kfet/tests/testcases.py | 4 +- kfet/tests/utils.py | 2 +- kfet/views.py | 28 ++++--- requirements-devel.txt | 2 +- requirements.txt | 18 ++--- utils/__init__.py | 0 utils/views/__init__.py | 0 utils/views/autocomplete.py | 26 +++++++ 44 files changed, 341 insertions(+), 278 deletions(-) delete mode 100644 bda/autocomplete_light_registry.py delete mode 100644 gestioncof/autocomplete_light_registry.py delete mode 100644 gestioncof/templates/admin/base_site.html delete mode 100644 gestioncof/templates/admin/index.html create mode 100644 utils/__init__.py create mode 100644 utils/views/__init__.py create mode 100644 utils/views/autocomplete.py diff --git a/bda/admin.py b/bda/admin.py index 60d3c1ba..6638ad45 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import autocomplete_light from datetime import timedelta from custommail.shortcuts import send_mass_custom_mail @@ -9,6 +8,9 @@ from django.db.models import Sum, Count from django.template.defaultfilters import pluralize from django.utils import timezone from django import forms + +from dal.autocomplete import ModelSelect2 + from bda.models import Spectacle, Salle, Participant, ChoixSpectacle,\ Attribution, Tirage, Quote, CategorieSpectacle, SpectacleRevente @@ -24,8 +26,17 @@ class ReadOnlyMixin(object): return readonly_fields + self.readonly_fields_update +class ChoixSpectacleAdminForm(forms.ModelForm): + class Meta: + widgets = { + 'participant': ModelSelect2(url='bda-participant-autocomplete'), + 'spectacle': ModelSelect2(url='bda-spectacle-autocomplete'), + } + + class ChoixSpectacleInline(admin.TabularInline): model = ChoixSpectacle + form = ChoixSpectacleAdminForm sortable_field_name = "priority" @@ -180,7 +191,7 @@ class AttributionAdmin(ReadOnlyMixin, admin.ModelAdmin): class ChoixSpectacleAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[]) + form = ChoixSpectacleAdminForm def tirage(self, obj): return obj.participant.tirage diff --git a/bda/autocomplete_light_registry.py b/bda/autocomplete_light_registry.py deleted file mode 100644 index 6c2f3ea6..00000000 --- a/bda/autocomplete_light_registry.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -import autocomplete_light - -from bda.models import Participant, Spectacle - -autocomplete_light.register( - Participant, search_fields=('user__username', 'user__first_name', - 'user__last_name'), - autocomplete_js_attributes={'placeholder': 'participant...'}) - -autocomplete_light.register( - Spectacle, search_fields=('title', ), - autocomplete_js_attributes={'placeholder': 'spectacle...'}) diff --git a/bda/migrations/0001_initial.py b/bda/migrations/0001_initial.py index aa2cb252..c4494413 100644 --- a/bda/migrations/0001_initial.py +++ b/bda/migrations/0001_initial.py @@ -59,7 +59,7 @@ class Migration(migrations.Migration): ('price', models.FloatField(verbose_name=b"Prix d'une place", blank=True)), ('slots', models.IntegerField(verbose_name=b'Places')), ('priority', models.IntegerField(default=1000, verbose_name=b'Priorit\xc3\xa9')), - ('location', models.ForeignKey(to='bda.Salle')), + ('location', models.ForeignKey(to='bda.Salle', on_delete=models.CASCADE)), ], options={ 'ordering': ('priority', 'date', 'title'), @@ -79,27 +79,27 @@ class Migration(migrations.Migration): migrations.AddField( model_name='participant', name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL), + field=models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='choixspectacle', name='participant', - field=models.ForeignKey(to='bda.Participant'), + field=models.ForeignKey(to='bda.Participant', on_delete=models.CASCADE), ), migrations.AddField( model_name='choixspectacle', name='spectacle', - field=models.ForeignKey(related_name='participants', to='bda.Spectacle'), + field=models.ForeignKey(related_name='participants', to='bda.Spectacle', on_delete=models.CASCADE), ), migrations.AddField( model_name='attribution', name='participant', - field=models.ForeignKey(to='bda.Participant'), + field=models.ForeignKey(to='bda.Participant', on_delete=models.CASCADE), ), migrations.AddField( model_name='attribution', name='spectacle', - field=models.ForeignKey(related_name='attribues', to='bda.Spectacle'), + field=models.ForeignKey(related_name='attribues', to='bda.Spectacle', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='choixspectacle', diff --git a/bda/migrations/0002_add_tirage.py b/bda/migrations/0002_add_tirage.py index 22c387a0..79f79a57 100644 --- a/bda/migrations/0002_add_tirage.py +++ b/bda/migrations/0002_add_tirage.py @@ -55,7 +55,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='participant', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), # Create fields `spectacle` for `Participant` and `Spectacle` models. # These fields are not nullable, but we first create them as nullable @@ -63,22 +63,22 @@ class Migration(migrations.Migration): migrations.AddField( model_name='participant', name='tirage', - field=models.ForeignKey(to='bda.Tirage', null=True), + field=models.ForeignKey(to='bda.Tirage', null=True, on_delete=models.CASCADE), ), migrations.AddField( model_name='spectacle', name='tirage', - field=models.ForeignKey(to='bda.Tirage', null=True), + field=models.ForeignKey(to='bda.Tirage', null=True, on_delete=models.CASCADE), ), migrations.RunPython(fill_tirage_fields, migrations.RunPython.noop), migrations.AlterField( model_name='participant', name='tirage', - field=models.ForeignKey(to='bda.Tirage'), + field=models.ForeignKey(to='bda.Tirage', on_delete=models.CASCADE), ), migrations.AlterField( model_name='spectacle', name='tirage', - field=models.ForeignKey(to='bda.Tirage'), + field=models.ForeignKey(to='bda.Tirage', on_delete=models.CASCADE), ), ] diff --git a/bda/migrations/0007_extends_spectacle.py b/bda/migrations/0007_extends_spectacle.py index b95c18de..6ea11dc0 100644 --- a/bda/migrations/0007_extends_spectacle.py +++ b/bda/migrations/0007_extends_spectacle.py @@ -73,6 +73,7 @@ class Migration(migrations.Migration): model_name='spectacle', name='category', field=models.ForeignKey(blank=True, to='bda.CategorieSpectacle', + on_delete=models.CASCADE, null=True), ), migrations.AddField( @@ -84,6 +85,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='quote', name='spectacle', - field=models.ForeignKey(to='bda.Spectacle'), + field=models.ForeignKey(to='bda.Spectacle', + on_delete=models.CASCADE), ), ] diff --git a/bda/migrations/0009_revente.py b/bda/migrations/0009_revente.py index 1cca4e86..70d6f338 100644 --- a/bda/migrations/0009_revente.py +++ b/bda/migrations/0009_revente.py @@ -47,12 +47,14 @@ class Migration(migrations.Migration): model_name='spectaclerevente', name='attribution', field=models.OneToOneField(to='bda.Attribution', + on_delete=models.CASCADE, related_name='revente'), ), migrations.AddField( model_name='spectaclerevente', name='seller', field=models.ForeignKey(to='bda.Participant', + on_delete=models.CASCADE, verbose_name='Vendeur', related_name='original_shows'), ), @@ -60,6 +62,7 @@ class Migration(migrations.Migration): model_name='spectaclerevente', name='soldTo', field=models.ForeignKey(to='bda.Participant', + on_delete=models.CASCADE, verbose_name='Vendue à', null=True, blank=True), ), diff --git a/bda/models.py b/bda/models.py index 41462d70..ba9ccf4a 100644 --- a/bda/models.py +++ b/bda/models.py @@ -59,9 +59,12 @@ class CategorieSpectacle(models.Model): class Spectacle(models.Model): title = models.CharField("Titre", max_length=300) - category = models.ForeignKey(CategorieSpectacle, blank=True, null=True) + category = models.ForeignKey( + CategorieSpectacle, on_delete=models.CASCADE, + blank=True, null=True, + ) date = models.DateTimeField("Date & heure") - location = models.ForeignKey(Salle) + location = models.ForeignKey(Salle, on_delete=models.CASCADE) vips = models.TextField('Personnalités', blank=True) description = models.TextField("Description", blank=True) slots_description = models.TextField("Description des places", blank=True) @@ -71,7 +74,7 @@ class Spectacle(models.Model): max_length=500) price = models.FloatField("Prix d'une place") slots = models.IntegerField("Places") - tirage = models.ForeignKey(Tirage) + tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE) listing = models.BooleanField("Les places sont sur listing") rappel_sent = models.DateTimeField("Mail de rappel envoyé", blank=True, null=True) @@ -135,7 +138,7 @@ class Spectacle(models.Model): class Quote(models.Model): - spectacle = models.ForeignKey(Spectacle) + spectacle = models.ForeignKey(Spectacle, on_delete=models.CASCADE) text = models.TextField('Citation') author = models.CharField('Auteur', max_length=200) @@ -149,7 +152,7 @@ PAYMENT_TYPES = ( class Participant(models.Model): - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) choices = models.ManyToManyField(Spectacle, through="ChoixSpectacle", related_name="chosen_by") @@ -160,7 +163,7 @@ class Participant(models.Model): paymenttype = models.CharField("Moyen de paiement", max_length=6, choices=PAYMENT_TYPES, blank=True) - tirage = models.ForeignKey(Tirage) + tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE) choicesrevente = models.ManyToManyField(Spectacle, related_name="subscribed", blank=True) @@ -176,8 +179,11 @@ DOUBLE_CHOICES = ( class ChoixSpectacle(models.Model): - participant = models.ForeignKey(Participant) - spectacle = models.ForeignKey(Spectacle, related_name="participants") + participant = models.ForeignKey(Participant, on_delete=models.CASCADE) + spectacle = models.ForeignKey( + Spectacle, on_delete=models.CASCADE, + related_name="participants", + ) priority = models.PositiveIntegerField("Priorité") double_choice = models.CharField("Nombre de places", default="1", choices=DOUBLE_CHOICES, @@ -204,8 +210,11 @@ class ChoixSpectacle(models.Model): class Attribution(models.Model): - participant = models.ForeignKey(Participant) - spectacle = models.ForeignKey(Spectacle, related_name="attribues") + participant = models.ForeignKey(Participant, on_delete=models.CASCADE) + spectacle = models.ForeignKey( + Spectacle, on_delete=models.CASCADE, + related_name="attribues", + ) given = models.BooleanField("Donnée", default=False) def __str__(self): @@ -214,18 +223,25 @@ class Attribution(models.Model): class SpectacleRevente(models.Model): - attribution = models.OneToOneField(Attribution, - related_name="revente") + attribution = models.OneToOneField( + Attribution, on_delete=models.CASCADE, + related_name="revente", + ) date = models.DateTimeField("Date de mise en vente", default=timezone.now) answered_mail = models.ManyToManyField(Participant, related_name="wanted", blank=True) - seller = models.ForeignKey(Participant, - related_name="original_shows", - verbose_name="Vendeur") - soldTo = models.ForeignKey(Participant, blank=True, null=True, - verbose_name="Vendue à") + seller = models.ForeignKey( + Participant, on_delete=models.CASCADE, + verbose_name="Vendeur", + related_name="original_shows", + ) + soldTo = models.ForeignKey( + Participant, on_delete=models.CASCADE, + verbose_name="Vendue à", + blank=True, null=True, + ) notif_sent = models.BooleanField("Notification envoyée", default=False) diff --git a/bda/urls.py b/bda/urls.py index 876c84ea..6acc1746 100644 --- a/bda/urls.py +++ b/bda/urls.py @@ -32,6 +32,12 @@ urlpatterns = [ url(r'^spectacles/unpaid/(?P\d+)$', views.unpaid, name="bda-unpaid"), + url(r'^spectacles/autocomplete$', + views.spectacle_autocomplete, + name="bda-spectacle-autocomplete"), + url(r'^participants/autocomplete$', + views.participant_autocomplete, + name="bda-participant-autocomplete"), url(r'^liste-revente/(?P\d+)$', views.list_revente, name="bda-liste-revente"), diff --git a/bda/views.py b/bda/views.py index 84b6c9d3..6c4edff8 100644 --- a/bda/views.py +++ b/bda/views.py @@ -33,6 +33,8 @@ from bda.forms import ( InscriptionInlineFormSet, ) +from utils.views.autocomplete import Select2QuerySetView + @cof_required def etat_places(request, tirage_id): @@ -813,3 +815,26 @@ def catalogue(request, request_type): return JsonResponse(data_return, safe=False) # Si la requête n'est pas de la forme attendue, on quitte avec une erreur return HttpResponseBadRequest() + + +## +# Autocomplete views +# +# https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#create-an-autocomplete-view +## + + +class ParticipantAutocomplete(Select2QuerySetView): + model = Participant + search_fields = ('user__username', 'user__first_name', 'user__last_name') + + +participant_autocomplete = buro_required(ParticipantAutocomplete.as_view()) + + +class SpectacleAutocomplete(Select2QuerySetView): + model = Spectacle + search_fields = ('title',) + + +spectacle_autocomplete = buro_required(SpectacleAutocomplete.as_view()) diff --git a/cof/settings/common.py b/cof/settings/common.py index a2ea3f5e..48242fc3 100644 --- a/cof/settings/common.py +++ b/cof/settings/common.py @@ -57,17 +57,22 @@ BASE_DIR = os.path.dirname( # Application definition INSTALLED_APPS = [ 'gestioncof', + + # Must be before 'django.contrib.admin'. + # https://django-autocomplete-light.readthedocs.io/en/master/install.html + 'dal', + 'dal_select2', + 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', - 'grappelli', 'django.contrib.admin', 'django.contrib.admindocs', + 'bda', - 'autocomplete_light', 'captcha', 'django_cas_ng', 'bootstrapform', @@ -96,7 +101,7 @@ INSTALLED_APPS = [ 'kfet.cms', ] -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -124,9 +129,9 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', - 'django.core.context_processors.i18n', - 'django.core.context_processors.media', - 'django.core.context_processors.static', + 'django.template.context_processors.i18n', + 'django.template.context_processors.media', + 'django.template.context_processors.static', 'wagtailmenus.context_processors.wagtailmenus', 'djconfig.context_processors.config', 'gestioncof.shared.context_processor', diff --git a/cof/settings/dev.py b/cof/settings/dev.py index 9c622063..6e1f6b11 100644 --- a/cof/settings/dev.py +++ b/cof/settings/dev.py @@ -4,7 +4,7 @@ The settings that are not listed here are imported from .common """ from .common import * # NOQA -from .common import INSTALLED_APPS, MIDDLEWARE_CLASSES +from .common import INSTALLED_APPS, MIDDLEWARE EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' @@ -37,10 +37,11 @@ def show_toolbar(request): return DEBUG INSTALLED_APPS += ["debug_toolbar", "debug_panel"] -MIDDLEWARE_CLASSES = ( - ["debug_panel.middleware.DebugPanelMiddleware"] - + MIDDLEWARE_CLASSES -) + +MIDDLEWARE = [ + "debug_panel.middleware.DebugPanelMiddleware" +] + MIDDLEWARE + DEBUG_TOOLBAR_CONFIG = { 'SHOW_TOOLBAR_CALLBACK': show_toolbar, } diff --git a/cof/urls.py b/cof/urls.py index f62d5f01..e6e5d313 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -4,8 +4,6 @@ Fichier principal de configuration des urls du projet GestioCOF """ -import autocomplete_light - from django.conf import settings from django.conf.urls import include, url from django.conf.urls.static import static @@ -24,7 +22,6 @@ from gestioncof.urls import export_patterns, petitcours_patterns, \ clubs_patterns from gestioncof.autocomplete import autocomplete -autocomplete_light.autodiscover() admin.autodiscover() urlpatterns = [ @@ -49,18 +46,22 @@ urlpatterns = [ name="cof-denied"), url(r'^cas/login$', django_cas_views.login, name="cas_login_view"), url(r'^cas/logout$', django_cas_views.logout), - url(r'^outsider/login$', gestioncof_views.login_ext), + url(r'^outsider/login$', gestioncof_views.login_ext, + name="ext_login_view"), url(r'^outsider/logout$', django_views.logout, {'next_page': 'home'}), url(r'^login$', gestioncof_views.login, name="cof-login"), url(r'^logout$', gestioncof_views.logout, name="cof-logout"), # Infos persos - url(r'^profile$', gestioncof_views.profile), - url(r'^outsider/password-change$', django_views.password_change), + url(r'^profile$', gestioncof_views.profile, + name='profile'), + url(r'^outsider/password-change$', django_views.password_change, + name='password_change'), url(r'^outsider/password-change-done$', django_views.password_change_done, name='password_change_done'), # Inscription d'un nouveau membre - url(r'^registration$', gestioncof_views.registration), + url(r'^registration$', gestioncof_views.registration, + name='registration'), url(r'^registration/clipper/(?P[\w-]+)/' r'(?P.*)$', gestioncof_views.registration_form2, name="clipper-registration"), @@ -70,7 +71,8 @@ urlpatterns = [ name="empty-registration"), # Autocompletion url(r'^autocomplete/registration$', autocomplete), - url(r'^autocomplete/', include('autocomplete_light.urls')), + url(r'^user/autocomplete$', gestioncof_views.user_autocomplete, + name='cof-user-autocomplete'), # Interface admin url(r'^admin/logout/', gestioncof_views.logout), url(r'^admin/doc/', include('django.contrib.admindocs.urls')), @@ -78,10 +80,11 @@ urlpatterns = [ csv_views.admin_list_export, {'fields': ['username', ]}), url(r'^admin/', include(admin.site.urls)), - url(r'^grappelli/', include('grappelli.urls')), # Liens utiles du COF et du BdA - url(r'^utile_cof$', gestioncof_views.utile_cof), - url(r'^utile_bda$', gestioncof_views.utile_bda), + url(r'^utile_cof$', gestioncof_views.utile_cof, + name='utile_cof'), + url(r'^utile_bda$', gestioncof_views.utile_bda, + name='utile_bda'), url(r'^utile_bda/bda_diff$', gestioncof_views.liste_bdadiff), url(r'^utile_cof/diff_cof$', gestioncof_views.liste_diffcof), url(r'^utile_bda/bda_revente$', gestioncof_views.liste_bdarevente), diff --git a/gestioncof/admin.py b/gestioncof/admin.py index 0d7d7143..51969822 100644 --- a/gestioncof/admin.py +++ b/gestioncof/admin.py @@ -13,7 +13,7 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe from django.db.models import Q -import autocomplete_light +from dal.autocomplete import ModelSelect2 def add_link_field(target_model='', field='', link_text=str, @@ -217,8 +217,16 @@ def user_str(self): User.__str__ = user_str +class EventRegistrationAdminForm(forms.ModelForm): + class Meta: + widgets = { + 'user': ModelSelect2(url='cof-user-autocomplete'), + } + + class EventRegistrationAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(EventRegistration, exclude=[]) + form = EventRegistrationAdminForm + list_display = ('__str__', 'event', 'user', 'paid') list_filter = ('paid',) search_fields = ('user__username', 'user__first_name', 'user__last_name', diff --git a/gestioncof/autocomplete_light_registry.py b/gestioncof/autocomplete_light_registry.py deleted file mode 100644 index 4c62d995..00000000 --- a/gestioncof/autocomplete_light_registry.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -import autocomplete_light - -from django.contrib.auth.models import User - -autocomplete_light.register( - User, search_fields=('username', 'first_name', 'last_name'), - attrs={'placeholder': 'membre...'} -) diff --git a/gestioncof/migrations/0001_initial.py b/gestioncof/migrations/0001_initial.py index b942645d..c6bb6151 100644 --- a/gestioncof/migrations/0001_initial.py +++ b/gestioncof/migrations/0001_initial.py @@ -48,7 +48,7 @@ class Migration(migrations.Migration): ('is_buro', models.BooleanField(default=False, verbose_name=b'Membre du Bur\xc3\xb4')), ('petits_cours_accept', models.BooleanField(default=False, verbose_name=b'Recevoir des petits cours')), ('petits_cours_remarques', models.TextField(default=b'', verbose_name='Remarques et pr\xe9cisions pour les petits cours', blank=True)), - ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Profil COF', @@ -91,7 +91,7 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=200, verbose_name=b'Champ')), ('fieldtype', models.CharField(default=b'text', max_length=10, verbose_name=b'Type', choices=[(b'text', 'Texte long'), (b'char', 'Texte court')])), ('default', models.TextField(verbose_name=b'Valeur par d\xc3\xa9faut', blank=True)), - ('event', models.ForeignKey(related_name='commentfields', to='gestioncof.Event')), + ('event', models.ForeignKey(related_name='commentfields', to='gestioncof.Event', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Champ', @@ -102,7 +102,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('content', models.TextField(null=True, verbose_name=b'Contenu', blank=True)), - ('commentfield', models.ForeignKey(related_name='values', to='gestioncof.EventCommentField')), + ('commentfield', models.ForeignKey(related_name='values', to='gestioncof.EventCommentField', on_delete=models.CASCADE)), ], ), migrations.CreateModel( @@ -111,7 +111,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('name', models.CharField(max_length=200, verbose_name=b'Option')), ('multi_choices', models.BooleanField(default=False, verbose_name=b'Choix multiples')), - ('event', models.ForeignKey(related_name='options', to='gestioncof.Event')), + ('event', models.ForeignKey(related_name='options', to='gestioncof.Event', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Option', @@ -122,7 +122,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('value', models.CharField(max_length=200, verbose_name=b'Valeur')), - ('event_option', models.ForeignKey(related_name='choices', to='gestioncof.EventOption')), + ('event_option', models.ForeignKey(related_name='choices', to='gestioncof.EventOption', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Choix', @@ -133,10 +133,10 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('paid', models.BooleanField(default=False, verbose_name=b'A pay\xc3\xa9')), - ('event', models.ForeignKey(to='gestioncof.Event')), + ('event', models.ForeignKey(to='gestioncof.Event', on_delete=models.CASCADE)), ('filledcomments', models.ManyToManyField(to='gestioncof.EventCommentField', through='gestioncof.EventCommentValue')), ('options', models.ManyToManyField(to='gestioncof.EventOptionChoice')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Inscription', @@ -240,7 +240,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('question', models.CharField(max_length=200, verbose_name=b'Question')), ('multi_answers', models.BooleanField(default=False, verbose_name=b'Choix multiples')), - ('survey', models.ForeignKey(related_name='questions', to='gestioncof.Survey')), + ('survey', models.ForeignKey(related_name='questions', to='gestioncof.Survey', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Question', @@ -251,7 +251,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('answer', models.CharField(max_length=200, verbose_name=b'R\xc3\xa9ponse')), - ('survey_question', models.ForeignKey(related_name='answers', to='gestioncof.SurveyQuestion')), + ('survey_question', models.ForeignKey(related_name='answers', to='gestioncof.SurveyQuestion', on_delete=models.CASCADE)), ], options={ 'verbose_name': 'R\xe9ponse', @@ -265,12 +265,12 @@ class Migration(migrations.Migration): migrations.AddField( model_name='surveyanswer', name='survey', - field=models.ForeignKey(to='gestioncof.Survey'), + field=models.ForeignKey(to='gestioncof.Survey', on_delete=models.CASCADE), ), migrations.AddField( model_name='surveyanswer', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursdemande', @@ -280,47 +280,47 @@ class Migration(migrations.Migration): migrations.AddField( model_name='petitcoursdemande', name='traitee_par', - field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True), + field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursattributioncounter', name='matiere', - field=models.ForeignKey(verbose_name='Matiere', to='gestioncof.PetitCoursSubject'), + field=models.ForeignKey(verbose_name='Matiere', to='gestioncof.PetitCoursSubject', on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursattributioncounter', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursattribution', name='demande', - field=models.ForeignKey(verbose_name='Demande', to='gestioncof.PetitCoursDemande'), + field=models.ForeignKey(verbose_name='Demande', to='gestioncof.PetitCoursDemande', on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursattribution', name='matiere', - field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject'), + field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject', on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursattribution', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursability', name='matiere', - field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject'), + field=models.ForeignKey(verbose_name='Mati\xe8re', to='gestioncof.PetitCoursSubject', on_delete=models.CASCADE), ), migrations.AddField( model_name='petitcoursability', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE), ), migrations.AddField( model_name='eventcommentvalue', name='registration', - field=models.ForeignKey(related_name='comments', to='gestioncof.EventRegistration'), + field=models.ForeignKey(related_name='comments', to='gestioncof.EventRegistration', on_delete=models.CASCADE), ), migrations.AlterUniqueTogether( name='surveyanswer', diff --git a/gestioncof/migrations/0006_add_calendar.py b/gestioncof/migrations/0006_add_calendar.py index 004d3602..27852f61 100644 --- a/gestioncof/migrations/0006_add_calendar.py +++ b/gestioncof/migrations/0006_add_calendar.py @@ -23,7 +23,8 @@ class Migration(migrations.Migration): ('subscribe_to_events', models.BooleanField(default=True)), ('subscribe_to_my_shows', models.BooleanField(default=True)), ('other_shows', models.ManyToManyField(to='bda.Spectacle')), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, + on_delete=models.CASCADE)), ], ), migrations.AlterModelOptions( diff --git a/gestioncof/models.py b/gestioncof/models.py index ea2cacc4..0d816155 100644 --- a/gestioncof/models.py +++ b/gestioncof/models.py @@ -49,7 +49,10 @@ class CofProfile(models.Model): (COTIZ_GRATIS, _("Gratuit")), ) - user = models.OneToOneField(User, related_name="profile") + user = models.OneToOneField( + User, on_delete=models.CASCADE, + related_name="profile", + ) login_clipper = models.CharField( "Login clipper", max_length=32, blank=True ) @@ -130,7 +133,10 @@ class Event(models.Model): class EventCommentField(models.Model): - event = models.ForeignKey(Event, related_name="commentfields") + event = models.ForeignKey( + Event, on_delete=models.CASCADE, + related_name="commentfields", + ) name = models.CharField("Champ", max_length=200) fieldtype = models.CharField("Type", max_length=10, choices=TYPE_COMMENT_FIELD, default="text") @@ -144,9 +150,14 @@ class EventCommentField(models.Model): class EventCommentValue(models.Model): - commentfield = models.ForeignKey(EventCommentField, related_name="values") - registration = models.ForeignKey("EventRegistration", - related_name="comments") + commentfield = models.ForeignKey( + EventCommentField, on_delete=models.CASCADE, + related_name="values", + ) + registration = models.ForeignKey( + "EventRegistration", on_delete=models.CASCADE, + related_name="comments", + ) content = models.TextField("Contenu", blank=True, null=True) def __str__(self): @@ -154,7 +165,10 @@ class EventCommentValue(models.Model): class EventOption(models.Model): - event = models.ForeignKey(Event, related_name="options") + event = models.ForeignKey( + Event, on_delete=models.CASCADE, + related_name="options", + ) name = models.CharField("Option", max_length=200) multi_choices = models.BooleanField("Choix multiples", default=False) @@ -166,7 +180,10 @@ class EventOption(models.Model): class EventOptionChoice(models.Model): - event_option = models.ForeignKey(EventOption, related_name="choices") + event_option = models.ForeignKey( + EventOption, on_delete=models.CASCADE, + related_name="choices", + ) value = models.CharField("Valeur", max_length=200) class Meta: @@ -178,8 +195,8 @@ class EventOptionChoice(models.Model): class EventRegistration(models.Model): - user = models.ForeignKey(User) - event = models.ForeignKey(Event) + user = models.ForeignKey(User, on_delete=models.CASCADE) + event = models.ForeignKey(Event, on_delete=models.CASCADE) options = models.ManyToManyField(EventOptionChoice) filledcomments = models.ManyToManyField(EventCommentField, through=EventCommentValue) @@ -207,7 +224,10 @@ class Survey(models.Model): class SurveyQuestion(models.Model): - survey = models.ForeignKey(Survey, related_name="questions") + survey = models.ForeignKey( + Survey, on_delete=models.CASCADE, + related_name="questions", + ) question = models.CharField("Question", max_length=200) multi_answers = models.BooleanField("Choix multiples", default=False) @@ -219,7 +239,10 @@ class SurveyQuestion(models.Model): class SurveyQuestionAnswer(models.Model): - survey_question = models.ForeignKey(SurveyQuestion, related_name="answers") + survey_question = models.ForeignKey( + SurveyQuestion, on_delete=models.CASCADE, + related_name="answers", + ) answer = models.CharField("Réponse", max_length=200) class Meta: @@ -230,8 +253,8 @@ class SurveyQuestionAnswer(models.Model): class SurveyAnswer(models.Model): - user = models.ForeignKey(User) - survey = models.ForeignKey(Survey) + user = models.ForeignKey(User, on_delete=models.CASCADE) + survey = models.ForeignKey(Survey, on_delete=models.CASCADE) answers = models.ManyToManyField(SurveyQuestionAnswer, related_name="selected_by") @@ -247,7 +270,7 @@ class SurveyAnswer(models.Model): class CalendarSubscription(models.Model): token = models.UUIDField() - user = models.OneToOneField(User) + user = models.OneToOneField(User, on_delete=models.CASCADE) other_shows = models.ManyToManyField(Spectacle) subscribe_to_events = models.BooleanField(default=True) subscribe_to_my_shows = models.BooleanField(default=True) diff --git a/gestioncof/petits_cours_models.py b/gestioncof/petits_cours_models.py index d9ea9668..bf2cfde9 100644 --- a/gestioncof/petits_cours_models.py +++ b/gestioncof/petits_cours_models.py @@ -35,8 +35,11 @@ class PetitCoursSubject(models.Model): class PetitCoursAbility(models.Model): - user = models.ForeignKey(User) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière")) + user = models.ForeignKey(User, on_delete=models.CASCADE) + matiere = models.ForeignKey( + PetitCoursSubject, on_delete=models.CASCADE, + verbose_name=_("Matière"), + ) niveau = models.CharField(_("Niveau"), choices=LEVELS_CHOICES, max_length=choices_length(LEVELS_CHOICES)) @@ -84,7 +87,10 @@ class PetitCoursDemande(models.Model): remarques = models.TextField(_("Remarques et précisions"), blank=True) traitee = models.BooleanField(_("Traitée"), default=False) - traitee_par = models.ForeignKey(User, blank=True, null=True) + traitee_par = models.ForeignKey( + User, on_delete=models.CASCADE, + blank=True, null=True, + ) processed = models.DateTimeField(_("Date de traitement"), blank=True, null=True) created = models.DateTimeField(_("Date de création"), auto_now_add=True) @@ -126,9 +132,15 @@ class PetitCoursDemande(models.Model): class PetitCoursAttribution(models.Model): - user = models.ForeignKey(User) - demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande")) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière")) + user = models.ForeignKey(User, on_delete=models.CASCADE) + demande = models.ForeignKey( + PetitCoursDemande, on_delete=models.CASCADE, + verbose_name=_("Demande"), + ) + matiere = models.ForeignKey( + PetitCoursSubject, on_delete=models.CASCADE, + verbose_name=_("Matière"), + ) date = models.DateTimeField(_("Date d'attribution"), auto_now_add=True) rank = models.IntegerField("Rang dans l'email") selected = models.BooleanField(_("Sélectionné par le demandeur"), @@ -145,8 +157,11 @@ class PetitCoursAttribution(models.Model): class PetitCoursAttributionCounter(models.Model): - user = models.ForeignKey(User) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere")) + user = models.ForeignKey(User, on_delete=models.CASCADE) + matiere = models.ForeignKey( + PetitCoursSubject, on_delete=models.CASCADE, + verbose_name=_("Matiere"), + ) count = models.IntegerField("Nombre d'envois", default=0) @classmethod diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index 087c9cef..52a29883 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- import json -from datetime import datetime from custommail.shortcuts import render_custom_mail from django.shortcuts import render, get_object_or_404, redirect @@ -13,6 +12,7 @@ from django.conf import settings from django.contrib.auth.decorators import login_required from django.contrib import messages from django.db import transaction +from django.utils import timezone from gestioncof.models import CofProfile from gestioncof.petits_cours_models import ( @@ -287,7 +287,7 @@ def _traitement_post(request, demande): attrib.save() demande.traitee = True demande.traitee_par = request.user - demande.processed = datetime.now() + demande.processed = timezone.now() demande.save() return render(request, "gestioncof/traitement_demande_petit_cours_success.html", diff --git a/gestioncof/templates/admin/base_site.html b/gestioncof/templates/admin/base_site.html deleted file mode 100644 index 03fd0d17..00000000 --- a/gestioncof/templates/admin/base_site.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "admin/base.html" %} - -{% block extrahead %} - - {% include 'autocomplete_light/static.html' %} -{% endblock %} diff --git a/gestioncof/templates/admin/index.html b/gestioncof/templates/admin/index.html deleted file mode 100644 index 965c71fa..00000000 --- a/gestioncof/templates/admin/index.html +++ /dev/null @@ -1,78 +0,0 @@ -{% extends "admin/base_site.html" %} - - -{% load i18n grp_tags log %} - - -{% block javascripts %} - {{ block.super }} -{% endblock %} - - -{% block breadcrumbs %} -
    -
  • {% trans "Home" %}
  • -
-{% endblock %} -{% block content_title %} - {% if title %} -

{{ title }}

- {% endif %} -{% endblock %} - - -{% block content %} -
-
- - {% for app in app_list %} -
-

{% trans app.name %}

- {% for model in app.models %} -
- {% if model.perms.change %}{{ model.name }}{% else %}{{ model.name }}{% endif %} - {% if model.perms.add or model.perms.change %} - - {% endif %} -
- {% endfor %} -
- {% empty %} -

{% trans "You don´t have permission to edit anything." %}

- {% endfor %} -
-
-
-

{% trans 'Recent Actions' %}

-
-

{% trans 'My Actions' %}

- {% get_admin_log 20 as admin_log for_user user %} - {% if not admin_log %} -

{% trans 'None available' %}

- {% else %} -
    - {% for entry in admin_log %} -
  • - {% if entry.is_deletion %} - {{ entry.object_repr }} - {% else %} - {{ entry.object_repr }} - {% endif %} - {% filter capfirst %}{% trans entry.content_type.name %}{% endfilter %} -
  • - {% endfor %} -
- {% endif %} -
-
-
-
-{% endblock %} - diff --git a/gestioncof/templates/gestioncof/base_header.html b/gestioncof/templates/gestioncof/base_header.html index 21441875..e5f757a7 100644 --- a/gestioncof/templates/gestioncof/base_header.html +++ b/gestioncof/templates/gestioncof/base_header.html @@ -3,7 +3,7 @@ {% block content %}
diff --git a/gestioncof/templates/gestioncof/event.html b/gestioncof/templates/gestioncof/event.html index 52f893db..f388bc25 100644 --- a/gestioncof/templates/gestioncof/event.html +++ b/gestioncof/templates/gestioncof/event.html @@ -5,7 +5,7 @@ {% if event.details %}

{{ event.details }}

{% endif %} -
+ {% csrf_token %} {{ form.as_p }} diff --git a/gestioncof/templates/home.html b/gestioncof/templates/home.html index acc04f30..65c4ba5e 100644 --- a/gestioncof/templates/home.html +++ b/gestioncof/templates/home.html @@ -14,7 +14,7 @@
@@ -24,7 +24,7 @@
@@ -69,11 +69,11 @@

Divers

{% endif %} @@ -86,16 +86,16 @@

Général

  • Administration générale
  • Demandes de petits cours
  • -
  • Inscription d'un nouveau membre
  • +
  • Inscription d'un nouveau membre
  • Gestion des clubs
  • @@ -120,8 +120,8 @@

    Liens utiles

    diff --git a/gestioncof/templates/login.html b/gestioncof/templates/login.html index 1cd1d25d..bfc2dbb8 100644 --- a/gestioncof/templates/login.html +++ b/gestioncof/templates/login.html @@ -15,7 +15,7 @@

    Identifiants incorrects.

    {% endif %} + action="{% url 'ext_login_view' %}?next={{ next|urlencode }}"> {% csrf_token %}
    diff --git a/gestioncof/templates/login_switch.html b/gestioncof/templates/login_switch.html index aa8a68c6..d361493b 100644 --- a/gestioncof/templates/login_switch.html +++ b/gestioncof/templates/login_switch.html @@ -12,13 +12,13 @@
    + href="{% url 'cas_login_view' %}?next={{ next|urlencode }}">
    Compte clipper
    + href="{% url 'ext_login_view' %}?next={{ next|urlencode }}">
    Extérieur
    diff --git a/gestioncof/templates/registration/password_change_done.html b/gestioncof/templates/registration/password_change_done.html index f83a781b..9f2c4a60 100644 --- a/gestioncof/templates/registration/password_change_done.html +++ b/gestioncof/templates/registration/password_change_done.html @@ -5,5 +5,5 @@ {% block realcontent %}

    Mot de passe modifié avec succès !

    -

    Retour au menu principal

    +

    Retour au menu principal

    {% endblock %} diff --git a/gestioncof/templates/registration/password_change_form.html b/gestioncof/templates/registration/password_change_form.html index f579fb31..d9a3f66a 100644 --- a/gestioncof/templates/registration/password_change_form.html +++ b/gestioncof/templates/registration/password_change_form.html @@ -5,7 +5,7 @@ {% block realcontent %}

    Changement de mot de passe

    - + {% csrf_token %} {{ form | bootstrap }} diff --git a/gestioncof/urls.py b/gestioncof/urls.py index 57c2e8f2..2be609b3 100644 --- a/gestioncof/urls.py +++ b/gestioncof/urls.py @@ -36,19 +36,23 @@ petitcours_patterns = [ ] surveys_patterns = [ - url(r'^(?P\d+)/status$', views.survey_status), - url(r'^(?P\d+)$', views.survey), + url(r'^(?P\d+)/status$', views.survey_status, + name='survey.details.status'), + url(r'^(?P\d+)$', views.survey, + name='survey.details'), ] events_patterns = [ - url(r'^(?P\d+)$', views.event), - url(r'^(?P\d+)/status$', views.event_status), + url(r'^(?P\d+)$', views.event, + name='event.details'), + url(r'^(?P\d+)/status$', views.event_status, + name='event.details.status'), ] calendar_patterns = [ - url(r'^subscription$', 'gestioncof.views.calendar'), - url(r'^(?P[a-z0-9-]+)/calendar.ics$', - 'gestioncof.views.calendar_ics') + url(r'^subscription$', views.calendar, + name='calendar'), + url(r'^(?P[a-z0-9-]+)/calendar.ics$', views.calendar_ics) ] clubs_patterns = [ diff --git a/gestioncof/views.py b/gestioncof/views.py index ec9f6efd..5dfee83f 100644 --- a/gestioncof/views.py +++ b/gestioncof/views.py @@ -20,6 +20,8 @@ from django.contrib import messages from django_cas_ng.views import logout as cas_logout_view +from utils.views.autocomplete import Select2QuerySetView + from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \ SurveyQuestionAnswer from gestioncof.models import Event, EventRegistration, EventOption, \ @@ -54,8 +56,8 @@ def home(request): def login(request): - if request.user.is_authenticated(): - return redirect("gestioncof.views.home") + if request.user.is_authenticated: + return redirect("home") context = {} if request.method == "GET" and 'next' in request.GET: context['next'] = request.GET['next'] @@ -786,3 +788,18 @@ class ConfigUpdate(FormView): def form_valid(self, form): form.save() return super().form_valid(form) + + +## +# Autocomplete views +# +# https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#create-an-autocomplete-view +## + + +class UserAutocomplete(Select2QuerySetView): + model = User + search_fields = ('username', 'first_name', 'last_name') + + +user_autocomplete = buro_required(UserAutocomplete.as_view()) diff --git a/kfet/auth/middleware.py b/kfet/auth/middleware.py index 748ce4dd..48d9c4ee 100644 --- a/kfet/auth/middleware.py +++ b/kfet/auth/middleware.py @@ -13,8 +13,11 @@ class TemporaryAuthMiddleware: values from CofProfile and Account of this user. """ - def process_request(self, request): - if request.user.is_authenticated(): + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + if request.user.is_authenticated: # avoid multiple db accesses in views and templates request.user = ( User.objects @@ -31,6 +34,8 @@ class TemporaryAuthMiddleware: request.real_user = request.user request.user = temp_request_user + return self.get_response(request) + def get_kfet_password(self, request): return ( request.META.get('HTTP_KFETPASSWORD') or diff --git a/kfet/auth/tests.py b/kfet/auth/tests.py index c2f183cd..0c8b25d3 100644 --- a/kfet/auth/tests.py +++ b/kfet/auth/tests.py @@ -286,6 +286,8 @@ class TemporaryAuthTests(TestCase): self.factory = RequestFactory() + self.middleware = TemporaryAuthMiddleware(mock.Mock()) + user1_acc = Account(trigramme='000') user1_acc.change_pwd('kfet_user1') user1_acc.save({'username': 'user1'}) @@ -312,7 +314,7 @@ class TemporaryAuthTests(TestCase): request = self.factory.get('/', HTTP_KFETPASSWORD='kfet_user2') request.user = self.user1 - TemporaryAuthMiddleware().process_request(request) + self.middleware(request) self.assertEqual(request.user, self.user2) self.assertEqual(request.real_user, self.user1) @@ -325,7 +327,7 @@ class TemporaryAuthTests(TestCase): request = self.factory.post('/', {'KFETPASSWORD': 'kfet_user2'}) request.user = self.user1 - TemporaryAuthMiddleware().process_request(request) + self.middleware(request) self.assertEqual(request.user, self.user2) self.assertEqual(request.real_user, self.user1) @@ -337,7 +339,7 @@ class TemporaryAuthTests(TestCase): request = self.factory.post('/', {'KFETPASSWORD': 'invalid'}) request.user = self.user1 - TemporaryAuthMiddleware().process_request(request) + self.middleware(request) self.assertEqual(request.user, self.user1) self.assertFalse(hasattr(request, 'real_user')) diff --git a/kfet/cms/migrations/0001_initial.py b/kfet/cms/migrations/0001_initial.py index 951637c7..ed0b0948 100644 --- a/kfet/cms/migrations/0001_initial.py +++ b/kfet/cms/migrations/0001_initial.py @@ -20,7 +20,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='KFetPage', fields=[ - ('page_ptr', models.OneToOneField(serialize=False, primary_key=True, parent_link=True, auto_created=True, to='wagtailcore.Page')), + ('page_ptr', models.OneToOneField(serialize=False, primary_key=True, parent_link=True, auto_created=True, to='wagtailcore.Page', on_delete=models.CASCADE)), ('no_header', models.BooleanField(verbose_name='Sans en-tête', help_text="Coché, l'en-tête (avec le titre) de la page n'est pas affiché.", default=False)), ('content', wagtail.wagtailcore.fields.StreamField((('rich', wagtail.wagtailcore.blocks.RichTextBlock(label='Éditeur')), ('carte', kfet.cms.models.MenuBlock()), ('group_team', wagtail.wagtailcore.blocks.StructBlock((('show_only', wagtail.wagtailcore.blocks.IntegerBlock(help_text='Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.', required=False, label='Montrer seulement')), ('members', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailsnippets.blocks.SnippetChooserBlock(kfet.cms.models.MemberTeam), classname='team-group', label='K-Fêt-eux-ses'))))), ('group', wagtail.wagtailcore.blocks.StreamBlock((('rich', wagtail.wagtailcore.blocks.RichTextBlock(label='Éditeur')), ('carte', kfet.cms.models.MenuBlock()), ('group_team', wagtail.wagtailcore.blocks.StructBlock((('show_only', wagtail.wagtailcore.blocks.IntegerBlock(help_text='Nombre initial de membres affichés. Laisser vide pour tou-te-s les afficher.', required=False, label='Montrer seulement')), ('members', wagtail.wagtailcore.blocks.ListBlock(wagtail.wagtailsnippets.blocks.SnippetChooserBlock(kfet.cms.models.MemberTeam), classname='team-group', label='K-Fêt-eux-ses')))))), label='Contenu groupé'))), verbose_name='Contenu')), ('layout', models.CharField(max_length=255, choices=[('kfet/base_col_1.html', 'Une colonne : centrée sur la page'), ('kfet/base_col_2.html', 'Deux colonnes : fixe à gauche, contenu à droite'), ('kfet/base_col_mult.html', 'Contenu scindé sur plusieurs colonnes')], help_text='Comment cette page devrait être affichée ?', verbose_name='Template', default='kfet/base_col_mult.html')), diff --git a/kfet/models.py b/kfet/models.py index b1e351d5..deee76eb 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from django.db import models -from django.core.urlresolvers import reverse from django.core.validators import RegexValidator from django.contrib.auth.models import User from gestioncof.models import CofProfile +from django.urls import reverse from django.utils.six.moves import reduce from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible diff --git a/kfet/templates/kfet/base_nav.html b/kfet/templates/kfet/base_nav.html index dda6c1ef..f4c07e05 100644 --- a/kfet/templates/kfet/base_nav.html +++ b/kfet/templates/kfet/base_nav.html @@ -1,10 +1,12 @@ {% load i18n static %} {% load wagtailcore_tags %} +{% slugurl "kfet" as kfet_home_url %} +