corrections + class views
This commit is contained in:
parent
406f92098f
commit
6ba168d286
81 changed files with 2756 additions and 2736 deletions
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
try:
|
||||
|
@ -31,64 +32,60 @@ DBPASSWD = import_secret("DBPASSWD")
|
|||
|
||||
ACCOUNT_CREATION_PASS = import_secret("ACCOUNT_CREATION_PASS")
|
||||
|
||||
|
||||
|
||||
BASE_DIR = os.path.join(
|
||||
os.path.dirname(__file__), "..", ".."
|
||||
)
|
||||
BASE_DIR = os.path.join(os.path.dirname(__file__), "..", "..")
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'trombonoscope',
|
||||
'actu',
|
||||
'colorful',
|
||||
'pads',
|
||||
'calendrier',
|
||||
'gestion.apps.GestionConfig',
|
||||
'partitions.apps.PartitionsConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'avatar',
|
||||
'instruments',
|
||||
"trombonoscope",
|
||||
"actu",
|
||||
"colorful",
|
||||
"pads",
|
||||
"calendrier",
|
||||
"gestion.apps.GestionConfig",
|
||||
"partitions.apps.PartitionsConfig",
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"avatar",
|
||||
"instruments",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
"django.middleware.locale.LocaleMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "Ernestophone.urls"
|
||||
|
||||
TEMPLATES = [{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
|
||||
],
|
||||
'libraries':{
|
||||
'changelang': 'gestion.templatetags.changelang',
|
||||
'modulo': 'gestion.templatetags.modulo',
|
||||
'autotranslate': 'gestion.templatetags.autotranslate',
|
||||
'halflength': 'gestion.templatetags.halflength',
|
||||
|
||||
}
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
"libraries": {
|
||||
"changelang": "gestion.templatetags.changelang",
|
||||
"modulo": "gestion.templatetags.modulo",
|
||||
"autotranslate": "gestion.templatetags.autotranslate",
|
||||
"halflength": "gestion.templatetags.halflength",
|
||||
},
|
||||
},
|
||||
}
|
||||
}]
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "Ernestophone.wsgi.application"
|
||||
|
||||
|
@ -104,51 +101,51 @@ DATABASES = {
|
|||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# I18n
|
||||
# I18n
|
||||
LANGUAGE_CODE = 'fr'
|
||||
LANGUAGE_CODE = "fr"
|
||||
LANGUAGES = (
|
||||
('fr', _('Français')),
|
||||
('en', _('English')),
|
||||
("fr", _("Français")),
|
||||
("en", _("English")),
|
||||
)
|
||||
TIME_ZONE = 'UTC'
|
||||
TIME_ZONE = "UTC"
|
||||
USE_I18N = True
|
||||
USE_L10N = True
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
LOCALE_PATHS = ( os.path.join(BASE_DIR, 'locale'), )
|
||||
LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),)
|
||||
|
||||
|
||||
AUTH_PROFILE_MODEL = 'gestion.ErnestoUser'
|
||||
AUTH_PROFILE_MODEL = "gestion.ErnestoUser"
|
||||
|
||||
LOGIN_URL = "/login"
|
||||
|
||||
AVATAR_CLEANUP_DELETED = True
|
||||
AVATAR_AUTO_GENERATE_SIZES = (250,)
|
||||
AVATAR_CHANGE_TEMPLATE = "trombonoscope/change_avatar.html"
|
||||
AVATAR_MAX_AVATARS_PER_USER=1
|
||||
AVATAR_EXPOSE_USERNAMES=False
|
||||
AVATAR_STORAGE_DIR="trombonoscope"
|
||||
AVATAR_ADD_TEMPLATE="trombonoscope/add_avatar.html"
|
||||
AVATAR_DELETE_TEMPLATE="trombonoscope/delete_avatar.html"
|
||||
AVATAR_DEFAULT_URL="Ernesto"
|
||||
AVATAR_PROVIDERS=(
|
||||
'avatar.providers.PrimaryAvatarProvider',
|
||||
'avatar.providers.DefaultAvatarProvider',
|
||||
)
|
||||
AVATAR_THUMB_FORMAT = 'JPEG'
|
||||
AVATAR_MAX_AVATARS_PER_USER = 1
|
||||
AVATAR_EXPOSE_USERNAMES = False
|
||||
AVATAR_STORAGE_DIR = "trombonoscope"
|
||||
AVATAR_ADD_TEMPLATE = "trombonoscope/add_avatar.html"
|
||||
AVATAR_DELETE_TEMPLATE = "trombonoscope/delete_avatar.html"
|
||||
AVATAR_DEFAULT_URL = "Ernesto"
|
||||
AVATAR_PROVIDERS = (
|
||||
"avatar.providers.PrimaryAvatarProvider",
|
||||
"avatar.providers.DefaultAvatarProvider",
|
||||
)
|
||||
AVATAR_THUMB_FORMAT = "JPEG"
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
import os
|
||||
|
||||
|
||||
from .common import * # noqa
|
||||
from .common import BASE_DIR, INSTALLED_APPS, MIDDLEWARE
|
||||
|
||||
|
||||
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
|
||||
|
||||
DEBUG = True
|
||||
|
||||
INSTALLED_APPS += ["debug_toolbar"]
|
||||
MIDDLEWARE = (
|
||||
["debug_toolbar.middleware.DebugToolbarMiddleware"]
|
||||
+ MIDDLEWARE
|
||||
)
|
||||
MIDDLEWARE = ["debug_toolbar.middleware.DebugToolbarMiddleware"] + MIDDLEWARE
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = "static"
|
||||
|
|
|
@ -3,7 +3,6 @@ import os
|
|||
from .common import * # noqa
|
||||
from .common import BASE_DIR
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = [
|
||||
|
@ -12,11 +11,7 @@ ALLOWED_HOSTS = [
|
|||
]
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
STATIC_ROOT = os.path.join(
|
||||
BASE_DIR, "..", "..", "public", "ernesto", "static"
|
||||
)
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, "..", "..", "public", "ernesto", "static")
|
||||
|
||||
MEDIA_URL = "/media/"
|
||||
MEDIA_ROOT = os.path.join(
|
||||
BASE_DIR, "..", "media"
|
||||
)
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "..", "media")
|
||||
|
|
|
@ -13,37 +13,39 @@ Including another URLconf
|
|||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from gestion import views as gestion_views
|
||||
from django.contrib.auth import views as auth_views
|
||||
import django.contrib.auth.urls as urls
|
||||
from django.conf.urls.static import static
|
||||
from django.conf import settings
|
||||
from django.conf.urls.i18n import i18n_patterns
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.urls import include, path
|
||||
|
||||
from gestion import views as gestion_views
|
||||
|
||||
urlpatterns = []
|
||||
urlpatterns += i18n_patterns(
|
||||
path('', gestion_views.home, name="home"),
|
||||
path("registration", gestion_views.inscription_membre, name="registration"),
|
||||
path("change", gestion_views.change_membre, name="change_membre"),
|
||||
path("password", gestion_views.change_password, name="change_password"),
|
||||
path("thanks", gestion_views.thanks, name="thanks"),
|
||||
path("changename", gestion_views.changename, name="change-doodle-name"),
|
||||
path("logout", auth_views.LogoutView.as_view(next_page="home"), name="logout"),
|
||||
path("", gestion_views.Home.as_view(), name="home"),
|
||||
path("registration", gestion_views.Inscription.as_view(),
|
||||
name="registration"),
|
||||
path("change", gestion_views.ChangeMembre.as_view(), name="change_membre"),
|
||||
path("password", gestion_views.ChangePassword.as_view(),
|
||||
name="change_password"),
|
||||
path("thanks", gestion_views.Thanks.as_view(), name="thanks"),
|
||||
path("changename", gestion_views.ChangeName.as_view(), name="change-doodle-name"),
|
||||
path("logout", auth_views.LogoutView.as_view(next_page="home"),
|
||||
name="logout"),
|
||||
path("login", gestion_views.MyLoginView.as_view(), name="login"),
|
||||
path("agenda/", include("calendrier.urls", namespace="calendrier")),
|
||||
path("partitions/", include("partitions.urls")),
|
||||
path("instruments/", include("instruments.urls")),
|
||||
path("pads/", include("pads.urls")),
|
||||
path(
|
||||
"login",
|
||||
gestion_views.MyLoginView.as_view(),
|
||||
name="login"
|
||||
"admin/",
|
||||
admin.site.urls,
|
||||
),
|
||||
path('agenda/', include('calendrier.urls',namespace='calendrier')),
|
||||
path('partitions/', include('partitions.urls')),
|
||||
path('instruments/', include('instruments.urls')),
|
||||
path('pads/', include('pads.urls')),
|
||||
path('admin/', admin.site.urls,),
|
||||
path('trombonoscope/',include('trombonoscope.urls')),
|
||||
path("actu/",include('actu.urls')),
|
||||
path('avatar/', include('avatar.urls')),
|
||||
prefix_default_language=False )
|
||||
path("trombonoscope/", include("trombonoscope.urls")),
|
||||
path("actu/", include("actu.urls")),
|
||||
path("avatar/", include("avatar.urls")),
|
||||
prefix_default_language=False,
|
||||
)
|
||||
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
"""
|
||||
WSGI config for Ernestophone project.
|
||||
|
||||
|
@ -10,10 +9,8 @@ https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
|
|||
|
||||
import os
|
||||
|
||||
os.environ.setdefault(
|
||||
"DJANGO_SETTINGS_MODULE",
|
||||
"Ernestophone.settings.prod"
|
||||
)
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings.prod")
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class ActuConfig(AppConfig):
|
||||
name = 'actu'
|
||||
name = "actu"
|
||||
|
|
|
@ -7,22 +7,34 @@ class Migration(migrations.Migration):
|
|||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Actu',
|
||||
name="Actu",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('text', models.TextField(null=True, verbose_name='Info')),
|
||||
('text_en', models.TextField(blank=True, null=True, verbose_name='Info en anglais')),
|
||||
('order', models.IntegerField(verbose_name='ordre')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("text", models.TextField(null=True, verbose_name="Info")),
|
||||
(
|
||||
"text_en",
|
||||
models.TextField(
|
||||
blank=True, null=True, verbose_name="Info en anglais"
|
||||
),
|
||||
),
|
||||
("order", models.IntegerField(verbose_name="ordre")),
|
||||
],
|
||||
options={
|
||||
'ordering': ('order',),
|
||||
'verbose_name_plural': 'Actualités',
|
||||
'verbose_name': 'Actualité',
|
||||
"ordering": ("order",),
|
||||
"verbose_name_plural": "Actualités",
|
||||
"verbose_name": "Actualité",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Actu(models.Model):
|
||||
|
||||
text = models.TextField(_("Info"), null=True, blank=False)
|
||||
text_en = models.TextField(("Info en anglais"), null=True, blank=True)
|
||||
order = models.IntegerField(verbose_name=_("ordre"))
|
||||
|
||||
def __str__(self):
|
||||
return self.text
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Actualité")
|
||||
verbose_name_plural = _("Actualités")
|
||||
ordering = ('order',)
|
||||
ordering = ("order",)
|
||||
|
|
|
@ -2,11 +2,10 @@ from django.urls import path
|
|||
|
||||
from actu import views
|
||||
|
||||
|
||||
app_name = "actu"
|
||||
urlpatterns = [
|
||||
path("", views.ActuList.as_view(), name="liste"),
|
||||
path("ajouter", views.ActuCreate.as_view(), name="add_actu"),
|
||||
path("edition/<int:pk>", views.ActuUpdate.as_view(), name="edit_actu"),
|
||||
path("supprimer/<int:pk>", views.ActuDelete.as_view(), name="delete_actu")
|
||||
path("supprimer/<int:pk>", views.ActuDelete.as_view(), name="delete_actu"),
|
||||
]
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from django.shortcuts import render
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
from actu.models import Actu
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
|
||||
from actu.models import Actu
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
|
||||
|
||||
class ActuList(ChefRequiredMixin, ListView):
|
||||
|
@ -14,7 +14,7 @@ class ActuList(ChefRequiredMixin, ListView):
|
|||
|
||||
class ActuCreate(ChefRequiredMixin, CreateView):
|
||||
model = Actu
|
||||
fields = ["text","order","text_en"]
|
||||
fields = ["text", "order", "text_en"]
|
||||
template_name = "actu/create_actu.html"
|
||||
success_url = reverse_lazy("actu:liste")
|
||||
|
||||
|
@ -26,7 +26,7 @@ class ActuCreate(ChefRequiredMixin, CreateView):
|
|||
|
||||
class ActuUpdate(ChefRequiredMixin, UpdateView):
|
||||
model = Actu
|
||||
fields = ["text","order","text_en"]
|
||||
fields = ["text", "order", "text_en"]
|
||||
template_name = "actu/update_actu.html"
|
||||
success_url = reverse_lazy("actu:liste")
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
from .models import Event
|
||||
|
||||
admin.site.register(Event)
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class CalendrierConfig(AppConfig):
|
||||
name = 'calendrier'
|
||||
name = "calendrier"
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
from django.utils.html import conditional_escape as esc
|
||||
from itertools import groupby
|
||||
from calendar import HTMLCalendar
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from datetime import date
|
||||
from itertools import groupby
|
||||
|
||||
from django.utils.html import conditional_escape as esc
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class EventCalendar(HTMLCalendar):
|
||||
|
||||
def __init__(self, pEvents):
|
||||
super(EventCalendar, self).__init__()
|
||||
self.events = self.group_by_day(pEvents.order_by('date'))
|
||||
self.events = self.group_by_day(pEvents.order_by("date"))
|
||||
|
||||
def formatday(self, day, weekday):
|
||||
if day != 0:
|
||||
cssclass = self.cssclasses[weekday]
|
||||
if date.today() == date(self.year, self.month, day):
|
||||
cssclass += ' today'
|
||||
cssclass += " today"
|
||||
if day in self.events:
|
||||
cssclass += ' filled'
|
||||
cssclass += " filled"
|
||||
body = []
|
||||
for ev in self.events[day]:
|
||||
body.append(_('<a href="/agenda/') + '%s">' % ev.id)
|
||||
body.append(esc(ev.nom))
|
||||
body.append('</a><br/>')
|
||||
return self.day_cell(cssclass,
|
||||
'<div class="dayNumber">%d</div> %s'
|
||||
% (day, ''.join(body)))
|
||||
return self.day_cell(cssclass,
|
||||
'<div class="dayNumber">%d</div>' % day)
|
||||
return self.day_cell('noday', ' ')
|
||||
body.append("</a><br/>")
|
||||
return self.day_cell(
|
||||
cssclass,
|
||||
'<div class="dayNumber">%d</div> %s' % (day, "".join(body)),
|
||||
)
|
||||
return self.day_cell(cssclass, '<div class="dayNumber">%d</div>' % day)
|
||||
return self.day_cell("noday", " ")
|
||||
|
||||
def formatmonth(self, year, month):
|
||||
self.year, self.month = year, month
|
||||
return super(EventCalendar, self).formatmonth(year, month)
|
||||
|
||||
def group_by_day(self, pEvents):
|
||||
def field(ev): return(ev.date.day)
|
||||
return dict(
|
||||
[(dat, list(items)) for dat, items in groupby(pEvents, field)]
|
||||
)
|
||||
def field(ev):
|
||||
return ev.date.day
|
||||
|
||||
return dict([(dat, list(items)) for dat, items in groupby(pEvents, field)])
|
||||
|
||||
def day_cell(self, cssclass, body):
|
||||
return '<td class="%s">%s</td>' % (cssclass, body)
|
||||
|
|
|
@ -1,61 +1,59 @@
|
|||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from calendrier.models import Event, Participants
|
||||
from gestion.models import ErnestoUser
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ModifEventForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Event
|
||||
exclude = ['slug']
|
||||
exclude = ["slug"]
|
||||
widgets = {
|
||||
'description': forms.Textarea(attrs={
|
||||
"placeholder": _("facultatif, balises html supportées")}),
|
||||
'date': forms.TextInput(attrs={"placeholder": 'jj/mm/aaaa'}),
|
||||
'debut': forms.TextInput(attrs={"placeholder": 'hh:mm'}),
|
||||
'fin': forms.TextInput(attrs={"placeholder": _('hh:mm facultatif')})
|
||||
"description": forms.Textarea(
|
||||
attrs={"placeholder": _("facultatif, balises html supportées")}
|
||||
),
|
||||
"date": forms.TextInput(attrs={"placeholder": "jj/mm/aaaa"}),
|
||||
"debut": forms.TextInput(attrs={"placeholder": "hh:mm"}),
|
||||
"fin": forms.TextInput(attrs={"placeholder": _("hh:mm facultatif")}),
|
||||
}
|
||||
|
||||
|
||||
|
||||
class EventForm(forms.ModelForm):
|
||||
|
||||
|
||||
class Meta:
|
||||
model = Event
|
||||
exclude = ['slug']
|
||||
exclude = ["slug"]
|
||||
widgets = {
|
||||
'nomcourt': forms.TextInput(
|
||||
attrs={"placeholder": _('9 caractères max')}),
|
||||
'description': forms.Textarea(
|
||||
attrs={"placeholder": _("facultatif, balises html supportées")}),
|
||||
'date': forms.TextInput(attrs={"placeholder": 'jj/mm/aaaa'}),
|
||||
'debut': forms.TextInput(attrs={"placeholder": 'hh:mm'}),
|
||||
'fin': forms.TextInput(attrs={"placeholder": _('hh:mm facultatif')}),
|
||||
"nomcourt": forms.TextInput(attrs={"placeholder": _("9 caractères max")}),
|
||||
"description": forms.Textarea(
|
||||
attrs={"placeholder": _("facultatif, balises html supportées")}
|
||||
),
|
||||
"date": forms.TextInput(attrs={"placeholder": "jj/mm/aaaa"}),
|
||||
"debut": forms.TextInput(attrs={"placeholder": "hh:mm"}),
|
||||
"fin": forms.TextInput(attrs={"placeholder": _("hh:mm facultatif")}),
|
||||
}
|
||||
|
||||
|
||||
class ParticipantsForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Participants
|
||||
fields = ('reponse', 'details')
|
||||
fields = ("reponse", "details")
|
||||
widgets = {
|
||||
'details': forms.Textarea(
|
||||
attrs={"placeholder": _("50 caractères max")}),
|
||||
"details": forms.Textarea(attrs={"placeholder": _("50 caractères max")}),
|
||||
}
|
||||
|
||||
|
||||
class ChangeDoodleName(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ChangeDoodleName, self).__init__(*args, **kwargs)
|
||||
self.fields['doodlename'].initial = self.instance.profile.get_doodlename()
|
||||
self.fields["doodlename"].initial = self.instance.profile.get_doodlename()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(ChangeDoodleName, self).save(*args, **kwargs)
|
||||
self.instance.profile.doodlename = self.cleaned_data['doodlename']
|
||||
self.instance.profile.doodlename = self.cleaned_data["doodlename"]
|
||||
self.instance.profile.save()
|
||||
self.instance.save()
|
||||
|
||||
class Meta:
|
||||
model = ErnestoUser
|
||||
fields = ('doodlename',)
|
||||
model = ErnestoUser
|
||||
fields = ("doodlename",)
|
||||
|
|
|
@ -7,37 +7,82 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestion', '0001_initial'),
|
||||
("gestion", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Event',
|
||||
name="Event",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('nomcourt', models.CharField(max_length=9, verbose_name='Nom court')),
|
||||
('date', models.DateField()),
|
||||
('debut', models.TimeField()),
|
||||
('fin', models.TimeField(blank=True, null=True)),
|
||||
('slug', models.CharField(max_length=7, editable=False, unique=True)),
|
||||
('lieu', models.CharField(max_length=200)),
|
||||
('description', models.TextField(blank=True)),
|
||||
('desc_users', models.TextField(blank=True, verbose_name='Infos (visible seulement des fanfaron-ne-s)', null=True)),
|
||||
('calendrier', models.BooleanField(verbose_name='Afficher dans le calendrier pour tous', default=False)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("nomcourt", models.CharField(max_length=9, verbose_name="Nom court")),
|
||||
("date", models.DateField()),
|
||||
("debut", models.TimeField()),
|
||||
("fin", models.TimeField(blank=True, null=True)),
|
||||
("slug", models.CharField(max_length=7, editable=False, unique=True)),
|
||||
("lieu", models.CharField(max_length=200)),
|
||||
("description", models.TextField(blank=True)),
|
||||
(
|
||||
"desc_users",
|
||||
models.TextField(
|
||||
blank=True,
|
||||
verbose_name="Infos (visible seulement des fanfaron-ne-s)",
|
||||
null=True,
|
||||
),
|
||||
),
|
||||
(
|
||||
"calendrier",
|
||||
models.BooleanField(
|
||||
verbose_name="Afficher dans le calendrier pour tous",
|
||||
default=False,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Événement',
|
||||
"verbose_name": "Événement",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Participants',
|
||||
name="Participants",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('reponse', models.CharField(max_length=20, choices=[('oui', 'Oui'), ('non', 'Non'), ('pe', 'Peut-être')], default='non', verbose_name='Réponse')),
|
||||
('details', models.CharField(blank=True, max_length=50)),
|
||||
('event', models.ForeignKey(to='calendrier.Event', on_delete=models.CASCADE)),
|
||||
('participant', models.ForeignKey(to='gestion.ErnestoUser', on_delete=models.CASCADE)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
(
|
||||
"reponse",
|
||||
models.CharField(
|
||||
max_length=20,
|
||||
choices=[("oui", "Oui"), ("non", "Non"), ("pe", "Peut-être")],
|
||||
default="non",
|
||||
verbose_name="Réponse",
|
||||
),
|
||||
),
|
||||
("details", models.CharField(blank=True, max_length=50)),
|
||||
(
|
||||
"event",
|
||||
models.ForeignKey(to="calendrier.Event", on_delete=models.CASCADE),
|
||||
),
|
||||
(
|
||||
"participant",
|
||||
models.ForeignKey(
|
||||
to="gestion.ErnestoUser", on_delete=models.CASCADE
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,43 +1,63 @@
|
|||
# Generated by Django 2.2.14 on 2020-07-14 15:59
|
||||
|
||||
from django.db import migrations, models
|
||||
import uuid
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('calendrier', '0001_initial'),
|
||||
("calendrier", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='event',
|
||||
options={'verbose_name': 'Evenement'},
|
||||
name="event",
|
||||
options={"verbose_name": "Evenement"},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='desc_users_en',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Infos en anglais (visible seulement des fanfaron-ne-s)'),
|
||||
model_name="event",
|
||||
name="desc_users_en",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Infos en anglais (visible seulement des fanfaron-ne-s)",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='description_en',
|
||||
model_name="event",
|
||||
name="description_en",
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='calendrier',
|
||||
field=models.CharField(choices=[('F', 'Visible seulement par les fanfarons'), ('T', 'Afficher dans le calendrier pour tous'), ('H', 'Hall of fame')], default='F', max_length=1),
|
||||
model_name="event",
|
||||
name="calendrier",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("F", "Visible seulement par les fanfarons"),
|
||||
("T", "Afficher dans le calendrier pour tous"),
|
||||
("H", "Hall of fame"),
|
||||
],
|
||||
default="F",
|
||||
max_length=1,
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='slug',
|
||||
field=models.CharField(default=uuid.uuid1, editable=False, max_length=7, unique=True),
|
||||
model_name="event",
|
||||
name="slug",
|
||||
field=models.CharField(
|
||||
default=uuid.uuid1, editable=False, max_length=7, unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='participants',
|
||||
name='reponse',
|
||||
field=models.CharField(choices=[('oui', 'Oui'), ('non', 'Non'), ('pe', 'Peut-etre')], default='non', max_length=20, verbose_name='Réponse'),
|
||||
model_name="participants",
|
||||
name="reponse",
|
||||
field=models.CharField(
|
||||
choices=[("oui", "Oui"), ("non", "Non"), ("pe", "Peut-etre")],
|
||||
default="non",
|
||||
max_length=20,
|
||||
verbose_name="Réponse",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,53 +1,62 @@
|
|||
from django.db import models
|
||||
import uuid
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from colorful.fields import RGBColorField
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
ANSWERS = (
|
||||
('oui', _('Oui')),
|
||||
('non', _('Non')),
|
||||
('pe', _('Peut-etre')),
|
||||
)
|
||||
("oui", _("Oui")),
|
||||
("non", _("Non")),
|
||||
("pe", _("Peut-etre")),
|
||||
)
|
||||
|
||||
|
||||
class Event(models.Model):
|
||||
|
||||
nom = models.CharField(max_length=100)
|
||||
nomcourt = models.CharField(max_length=9, verbose_name=_("Nom court"))
|
||||
date = models.DateField()
|
||||
debut = models.TimeField()
|
||||
fin = models.TimeField(blank=True, null=True)
|
||||
slug = models.CharField(max_length=7, editable=False, unique=True, default=uuid.uuid1)
|
||||
slug = models.CharField(
|
||||
max_length=7, editable=False, unique=True, default=uuid.uuid1
|
||||
)
|
||||
lieu = models.CharField(max_length=200)
|
||||
description = models.TextField(blank=True)
|
||||
description_en = models.TextField(blank=True)
|
||||
desc_users = models.TextField(
|
||||
blank=True,
|
||||
verbose_name=_("Infos (visible seulement des fanfaron-ne-s)"),
|
||||
null=True)
|
||||
blank=True,
|
||||
verbose_name=_("Infos (visible seulement des fanfaron-ne-s)"),
|
||||
null=True,
|
||||
)
|
||||
desc_users_en = models.TextField(
|
||||
blank=True,
|
||||
verbose_name=_("Infos en anglais (visible seulement des fanfaron-ne-s)"),
|
||||
null=True)
|
||||
blank=True,
|
||||
verbose_name=_("Infos en anglais (visible seulement des fanfaron-ne-s"),
|
||||
null=True,
|
||||
)
|
||||
CALENDRIER_CHOICES = [
|
||||
('F', _('Visible seulement par les fanfarons')),
|
||||
('T', _('Afficher dans le calendrier pour tous')),
|
||||
('H', _('Hall of fame')),
|
||||
("F", _("Visible seulement par les fanfarons")),
|
||||
("T", _("Afficher dans le calendrier pour tous")),
|
||||
("H", _("Hall of fame")),
|
||||
]
|
||||
calendrier = models.CharField(
|
||||
max_length=1,
|
||||
choices=CALENDRIER_CHOICES,
|
||||
default='F',
|
||||
default="F",
|
||||
)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return self.nom
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Evenement")
|
||||
|
||||
|
||||
class Participants(models.Model):
|
||||
event = models.ForeignKey(Event, on_delete=models.CASCADE)
|
||||
participant = models.ForeignKey(ErnestoUser, on_delete=models.CASCADE)
|
||||
reponse = models.CharField(_("Réponse"), max_length=20, default="non",
|
||||
choices=ANSWERS)
|
||||
reponse = models.CharField(
|
||||
_("Réponse"), max_length=20, default="non", choices=ANSWERS
|
||||
)
|
||||
details = models.CharField(max_length=50, blank=True)
|
||||
|
|
|
@ -73,6 +73,24 @@
|
|||
<div class="1u 12u$(small)"><p></p></div>
|
||||
<div class="5u 12u$(small)">
|
||||
|
||||
<span class="image fit">
|
||||
{% if photo %}
|
||||
<img src="{{photo.image.url}}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
{% if photo.url %}
|
||||
<a href="{{photo.url}}" target="_blank" class="icon fa-copyright" style="color: {{photo.color}}"> {% if photo.auteur %}{{photo.auteur}}{%endif%}</a>
|
||||
{% elif photo.auteur %}
|
||||
<div class="icon fa-copyright" style="color: {{photo.color}}" > {{photo.auteur}}</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/home.png' %}"/>
|
||||
<div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright"> lor_tie</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
{% if events_a_venir_not_answered %}
|
||||
<div class="box" style="background-color:#e4522f">
|
||||
<h1> {% blocktrans count counter=events_a_venir_not_answered|length %}Doodle à remplir !!!! :{% plural %}Doodles à remplir !!!! :{% endblocktrans %} </h1>
|
||||
|
@ -183,23 +201,6 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<span class="image fit">
|
||||
{% if photo %}
|
||||
<img src="{{photo.image.url}}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
{% if photo.url %}
|
||||
<a href="{{photo.url}}" target="_blank" class="icon fa-copyright" style="color: {{photo.color}}"> {% if photo.auteur %}{{photo.auteur}}{%endif%}</a>
|
||||
{% elif photo.auteur %}
|
||||
<div class="icon fa-copyright" style="color: {{photo.color}}" > {{photo.auteur}}</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/home.png' %}"/>
|
||||
<div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright"> lor_tie</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -20,7 +20,7 @@ def translate(tex):
|
|||
tex = tex.replace("December", "Décembre", 1)
|
||||
tex = tex.replace("Mon", "Lun", 1)
|
||||
tex = tex.replace("Tue", "Mar", 1)
|
||||
tex = tex.replace('Wed', "Mer", 1)
|
||||
tex = tex.replace("Wed", "Mer", 1)
|
||||
tex = tex.replace("Thu", "Jeu", 1)
|
||||
tex = tex.replace("Fri", "Ven", 1)
|
||||
tex = tex.replace("Sat", "Sam", 1)
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.test import Client, TestCase
|
|||
from django.utils import timezone
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
from ..models import Event
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -28,11 +29,7 @@ class TestViews(TestCase):
|
|||
ernesto = new_user("ernesto", ernesto=True)
|
||||
ernesto_c = Client()
|
||||
ernesto_c.force_login(ernesto)
|
||||
self.client_matrix = [
|
||||
(chef, chef_c),
|
||||
(ernesto, ernesto_c),
|
||||
(None, Client())
|
||||
]
|
||||
self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())]
|
||||
# A private and a public event
|
||||
now = timezone.now()
|
||||
later = now + timedelta(seconds=3600)
|
||||
|
@ -44,7 +41,7 @@ class TestViews(TestCase):
|
|||
fin=later.time(),
|
||||
slug="privevt",
|
||||
lieu="somewhere",
|
||||
calendrier=False
|
||||
calendrier=False,
|
||||
)
|
||||
self.pub_event = Event.objects.create(
|
||||
nom="public event",
|
||||
|
@ -54,7 +51,7 @@ class TestViews(TestCase):
|
|||
fin=later.time(),
|
||||
slug="pubevt",
|
||||
lieu="somewhere",
|
||||
calendrier=True
|
||||
calendrier=True,
|
||||
)
|
||||
|
||||
# Everyone can see theses pages
|
||||
|
@ -88,13 +85,16 @@ class TestViews(TestCase):
|
|||
chef, _ = self.client_matrix[0]
|
||||
codereps = ["oui", "non", "pe"]
|
||||
for coderep in codereps:
|
||||
url = "/calendar/rep/{}/{}/{}".format(chef.profile.slug, self.priv_event.slug, coderep)
|
||||
url = "/calendar/rep/{}/{}/{}".format(
|
||||
chef.profile.slug, self.priv_event.slug, coderep
|
||||
)
|
||||
self._everyone_can_get(url, redirect_url="/calendar/")
|
||||
|
||||
# Only ernesto members can get theses pages
|
||||
|
||||
def _get_restricted_page(self, url, chef_only=False, redirect_url=None):
|
||||
"""Shorthand for testing wether a page in only accessible by ernesto members"""
|
||||
|
||||
def user_allowed(user):
|
||||
if user is None:
|
||||
return False
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
from django.urls import path
|
||||
|
||||
from . import views
|
||||
from .views import EventUpdate, EventDelete
|
||||
from .views import EventDelete, EventUpdate
|
||||
|
||||
app_name = 'calendrier'
|
||||
app_name = "calendrier"
|
||||
urlpatterns = [
|
||||
path('', views.liste, name='liste'),
|
||||
path("calendar", views.home, name="home"),
|
||||
path("new", views.create_event, name="create_event"),
|
||||
path("", views.Agenda.as_view(), name="liste"),
|
||||
path("calendar", views.Home.as_view(), name="home"),
|
||||
path("new", views.CreateEvent.as_view(), name="create_event"),
|
||||
path("edition/<int:pk>", EventUpdate.as_view(), name="edit_event"),
|
||||
path("supprimer/<int:pk>", EventDelete.as_view(), name="delete_event"),
|
||||
path("<int:id>/changename", views.changename, name="change-doodle-name"),
|
||||
path("<int:id>/reponse", views.reponse, name="reponse"),
|
||||
path("<int:pYear>/<int:pMonth>", views.calendar, name="view-month"),
|
||||
path("<int:id>", views.view_event, name="view-event"),
|
||||
path("<int:id>/changename", views.ChangeName.as_view(),
|
||||
name="change-doodle-name"),
|
||||
path("<int:id>/reponse", views.ReponseEvent.as_view(), name="reponse"),
|
||||
path("<int:pYear>/<int:pMonth>", views.Calendar.as_view(),
|
||||
name="view-month"),
|
||||
path("<int:id>", views.ViewEvent.as_view(), name="view-event"),
|
||||
]
|
||||
|
|
|
@ -1,217 +1,312 @@
|
|||
import random
|
||||
import string
|
||||
from calendar import monthrange
|
||||
from collections import defaultdict
|
||||
from datetime import date, datetime
|
||||
import string
|
||||
import random
|
||||
|
||||
from django.db.models import Q
|
||||
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.sites.shortcuts import get_current_site
|
||||
from django.db.models import Count
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.views.generic import UpdateView, DeleteView
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.core.mail import send_mail
|
||||
from django.http import Http404
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.views.generic import DeleteView, UpdateView
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
from actu.models import Actu
|
||||
from calendrier.calend import EventCalendar
|
||||
from calendar import monthrange
|
||||
from calendrier.forms import ModifEventForm, EventForm, ParticipantsForm, ChangeDoodleName
|
||||
from calendrier.forms import (ChangeDoodleName, EventForm, ModifEventForm,
|
||||
ParticipantsForm)
|
||||
from calendrier.models import Event, Participants
|
||||
from gestion.models import Photo
|
||||
from partitions.decorators import chef_required
|
||||
|
||||
from django.views.generic import TemplateView
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
|
||||
|
||||
def generer(*args):
|
||||
caracteres = string.ascii_letters + string.digits
|
||||
aleatoire = [random.choice(caracteres) for _ in range(6)]
|
||||
return ''.join(aleatoire)
|
||||
|
||||
def liste(request):
|
||||
if request.user.is_authenticated :
|
||||
return redirect('calendrier:home')
|
||||
lToday = datetime.today()
|
||||
photo = Photo.objects.filter(cat='liste').order_by('?').first()
|
||||
events_a_venir = Event.objects.filter(date__gte = lToday).exclude(calendrier__iexact = 'F').order_by("-date")
|
||||
events_passe = Event.objects.filter(date__lt = lToday).filter(calendrier__iexact = 'H').order_by("-date")
|
||||
return render(request, 'calendrier/agenda.html', {"events_a_venir": events_a_venir,"events_passe":events_passe,"photo":photo})
|
||||
return "".join(aleatoire)
|
||||
|
||||
|
||||
def named_month(pMonthNumber):
|
||||
return date(1900, pMonthNumber, 1).strftime('%B')
|
||||
return date(1900, pMonthNumber, 1).strftime("%B")
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
|
||||
class Agenda(TemplateView):
|
||||
template_name = "calendrier/agenda.html"
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('calendrier:home')
|
||||
return super(Agenda, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
lToday = datetime.today()
|
||||
context['photo'] = Photo.objects.filter(
|
||||
cat="liste").order_by("?").first()
|
||||
context['events_a_venir'] = (
|
||||
Event.objects.filter(date__gte=lToday)
|
||||
.exclude(calendrier__iexact="F")
|
||||
.order_by("-date")
|
||||
)
|
||||
context['events_passe'] = (
|
||||
Event.objects.filter(date__lt=lToday)
|
||||
.filter(calendrier__iexact="H")
|
||||
.order_by("-date")
|
||||
)
|
||||
return context
|
||||
|
||||
|
||||
class Calendar(LoginRequiredMixin, TemplateView):
|
||||
template_name = "calendrier/home.html"
|
||||
|
||||
@property
|
||||
def pYear(self):
|
||||
return self.kwargs['pYear']
|
||||
|
||||
@property
|
||||
def pMonth(self):
|
||||
return self.kwargs['pMonth']
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Calendar, self).get_context_data(**kwargs)
|
||||
actu = Actu.objects.all()
|
||||
photo = Photo.objects.filter(cat="home").order_by("?").first()
|
||||
lToday = datetime.now()
|
||||
lYear = int(self.pYear)
|
||||
lMonth = int(self.pMonth)
|
||||
lCalendarFromMonth = datetime(lYear, lMonth, 1)
|
||||
lCalendarToMonth = datetime(lYear, lMonth,
|
||||
monthrange(lYear, lMonth)[1])
|
||||
lEvents = Event.objects.filter(
|
||||
date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth
|
||||
)
|
||||
lCalendar = EventCalendar(lEvents).formatmonth(lYear, lMonth)
|
||||
lPreviousYear = lYear
|
||||
lPreviousMonth = lMonth - 1
|
||||
if lPreviousMonth == 0:
|
||||
lPreviousMonth = 12
|
||||
lPreviousYear -= 1
|
||||
lNextYear = lYear
|
||||
lNextMonth = lMonth + 1
|
||||
if lNextMonth == 13:
|
||||
lNextMonth = 1
|
||||
lNextYear = lYear + 1
|
||||
lYearAfterThis = lYear + 1
|
||||
lYearBeforeThis = lYear - 1
|
||||
try:
|
||||
events_a_venir_not_answered = Event.objects.filter(
|
||||
date__gte=lToday).exclude(
|
||||
participants__participant=self.request.user.profile
|
||||
)
|
||||
events_a_venir_answered_yes = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant=self.request.user.profile)
|
||||
& Q(participants__reponse="oui")
|
||||
)
|
||||
events_a_venir_answered_no = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant=self.request.user.profile)
|
||||
& Q(participants__reponse="non")
|
||||
)
|
||||
events_a_venir_answered_pe = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant=self.request.user.profile)
|
||||
& Q(participants__reponse="pe")
|
||||
)
|
||||
except Event.DoesNotExist:
|
||||
events_a_venir_not_answered = Event.objects.filter(
|
||||
date__gte=lToday).exclude(
|
||||
participants__participant__user__username=self.request.user
|
||||
)
|
||||
events_a_venir_answered_yes = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant__user__username=self.request.user)
|
||||
& Q(participants__reponse="oui")
|
||||
)
|
||||
events_a_venir_answered_no = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant__user__username=self.request.user)
|
||||
& Q(participants__reponse="non")
|
||||
)
|
||||
events_a_venir_answered_pe = Event.objects.filter(
|
||||
date__gte=lToday).filter(
|
||||
Q(participants__participant__user__username=self.request.user)
|
||||
& Q(participants__reponse="pe")
|
||||
)
|
||||
|
||||
context["Calendar"] = mark_safe(lCalendar)
|
||||
context["Month"] = lMonth
|
||||
context["MonthName"] = named_month(lMonth)
|
||||
context["Year"] = lYear
|
||||
context["PreviousMonth"] = lPreviousMonth
|
||||
context["PreviousMonthName"] = named_month(lPreviousMonth)
|
||||
context["PreviousYear"] = lPreviousYear
|
||||
context["NextMonth"] = lNextMonth
|
||||
context["NextMonthName"] = named_month(lNextMonth)
|
||||
context["NextYear"] = lNextYear
|
||||
context["YearBeforeThis"] = lYearBeforeThis
|
||||
context["YearAfterThis"] = lYearAfterThis
|
||||
context["events_a_venir_answered_yes"] = events_a_venir_answered_yes
|
||||
context["events_a_venir_answered_no"] = events_a_venir_answered_no
|
||||
context["events_a_venir_answered_pe"] = events_a_venir_answered_pe
|
||||
context["events_a_venir_not_answered"] = events_a_venir_not_answered
|
||||
context["actu"] = actu
|
||||
context["photo"] = photo
|
||||
return context
|
||||
|
||||
|
||||
class Home(Calendar):
|
||||
lToday = datetime.now()
|
||||
return calendar(request, lToday.year, lToday.month)
|
||||
|
||||
@login_required
|
||||
def calendar(request, pYear, pMonth):
|
||||
actu = Actu.objects.all()
|
||||
photo = Photo.objects.filter(cat='home').order_by('?').first()
|
||||
lToday = datetime.now()
|
||||
lYear = int(pYear)
|
||||
lMonth = int(pMonth)
|
||||
lCalendarFromMonth = datetime(lYear, lMonth, 1)
|
||||
lCalendarToMonth = datetime(lYear, lMonth, monthrange(lYear, lMonth)[1])
|
||||
lEvents = Event.objects.filter(
|
||||
date__gte=lCalendarFromMonth, date__lte=lCalendarToMonth
|
||||
)
|
||||
if request.user.is_authenticated:
|
||||
lEvents = Event.objects.filter(date__gte=lCalendarFromMonth,
|
||||
date__lte=lCalendarToMonth)
|
||||
lCalendar = EventCalendar(lEvents).formatmonth(lYear, lMonth)
|
||||
lPreviousYear = lYear
|
||||
lPreviousMonth = lMonth - 1
|
||||
if lPreviousMonth == 0:
|
||||
lPreviousMonth = 12
|
||||
lPreviousYear -= 1
|
||||
lNextYear = lYear
|
||||
lNextMonth = lMonth + 1
|
||||
if lNextMonth == 13:
|
||||
lNextMonth = 1
|
||||
lNextYear = lYear + 1
|
||||
lYearAfterThis = lYear + 1
|
||||
lYearBeforeThis = lYear - 1
|
||||
try:
|
||||
events_a_venir_not_answered = Event.objects.filter(date__gte = lToday).exclude(participants__participant=request.user.profile)
|
||||
events_a_venir_answered = Event.objects.filter(date__gte = lToday).filter(participants__participant=request.user.profile)
|
||||
events_a_venir_answered_yes = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile )& Q(participants__reponse= 'oui'))
|
||||
events_a_venir_answered_no = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile) & Q(participants__reponse= 'non'))
|
||||
events_a_venir_answered_pe = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant=request.user.profile)& Q(participants__reponse= 'pe'))
|
||||
except:
|
||||
events_a_venir_not_answered = Event.objects.filter(date__gte = lToday).exclude(participants__participant__user__username=request.user)
|
||||
events_a_venir_answered = Event.objects.filter(date__gte = lToday).filter(participants__participant__user__username=request.user)
|
||||
events_a_venir_answered_yes = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user )& Q(participants__reponse= 'oui'))
|
||||
events_a_venir_answered_no = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user) & Q(participants__reponse= 'non'))
|
||||
events_a_venir_answered_pe = Event.objects.filter(date__gte = lToday).filter(Q(participants__participant__user__username=request.user)& Q(participants__reponse= 'pe'))
|
||||
return render(request, 'calendrier/home.html', {
|
||||
'Calendar': mark_safe(lCalendar),
|
||||
'Month': lMonth,
|
||||
'MonthName': named_month(lMonth),
|
||||
'Year': lYear,
|
||||
'PreviousMonth': lPreviousMonth,
|
||||
'PreviousMonthName': named_month(lPreviousMonth),
|
||||
'PreviousYear': lPreviousYear,
|
||||
'NextMonth': lNextMonth,
|
||||
'NextMonthName': named_month(lNextMonth),
|
||||
'NextYear': lNextYear,
|
||||
'YearBeforeThis': lYearBeforeThis,
|
||||
'YearAfterThis': lYearAfterThis,
|
||||
"events_a_venir_answered_yes": events_a_venir_answered_yes,
|
||||
"events_a_venir_answered_no": events_a_venir_answered_no,
|
||||
"events_a_venir_answered_pe": events_a_venir_answered_pe,
|
||||
"events_a_venir_not_answered": events_a_venir_not_answered,
|
||||
"actu" : actu,
|
||||
"photo" : photo,
|
||||
})
|
||||
@property
|
||||
def pYear(self):
|
||||
return self.lToday.year
|
||||
|
||||
@login_required
|
||||
def view_event(request, id):
|
||||
event = get_object_or_404(Event, id=id)
|
||||
participants = event.participants_set.all()
|
||||
multi_instrumentistes = event.participants_set.filter(Q(participant__multi_instrumentiste = 'Oui')& ~Q(reponse = 'non'))
|
||||
|
||||
# Restricted event, only erneso users can see it
|
||||
if not request.user.is_authenticated and not event.calendrier:
|
||||
return redirect(reverse('calendrier:home'))
|
||||
|
||||
# Count the number of occurences of each instrument
|
||||
instrument_count = defaultdict(lambda: (0, 0,[],[],[]))
|
||||
for participant in participants:
|
||||
instrument = participant.participant.instru
|
||||
if (instrument == "Autre"):
|
||||
instrument = participant.participant.instru_autre
|
||||
|
||||
sure, maybe, namesoui, namespe, namesnon = instrument_count[instrument]
|
||||
|
||||
if participant.reponse == "oui":
|
||||
|
||||
namesoui += [participant.participant.get_doodlename()]
|
||||
instrument_count[instrument] = (sure + 1, maybe,namesoui,namespe,namesnon)
|
||||
elif participant.reponse == "pe":
|
||||
namespe += [participant.participant.get_doodlename()]
|
||||
instrument_count[instrument] = (sure, maybe + 1,namesoui,namespe,namesnon)
|
||||
else:
|
||||
namesnon += [participant.participant.get_doodlename()]
|
||||
instrument_count[instrument] = (sure, maybe,namesoui,namespe,namesnon)
|
||||
|
||||
instrument_count = [
|
||||
(instrument, sure, maybe,namesoui, namespe ,namesnon)
|
||||
for instrument, (sure, maybe,namesoui,namespe,namesnon) in instrument_count.items()
|
||||
]
|
||||
|
||||
context = {
|
||||
"event": event,
|
||||
"instrument_count": instrument_count,
|
||||
"participants": participants,
|
||||
"nboui": len(participants.filter(reponse="oui")),
|
||||
"nbpe": len(participants.filter(reponse="pe")),
|
||||
"nbnon": len(participants.filter(reponse="non")),
|
||||
"multi_instrumentistes":multi_instrumentistes,
|
||||
}
|
||||
return render(request, 'calendrier/view_event.html', context=context)
|
||||
@property
|
||||
def pMonth(self):
|
||||
return self.lToday.month
|
||||
|
||||
|
||||
class ViewEvent(LoginRequiredMixin, TemplateView):
|
||||
template_name = "calendrier/view_event.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ViewEvent, self).get_context_data(**kwargs)
|
||||
event = get_object_or_404(Event, id=self.kwargs['id'])
|
||||
participants = event.participants_set.all()
|
||||
multi_instrumentistes = event.participants_set.filter(
|
||||
Q(participant__multi_instrumentiste="Oui") & ~Q(reponse="non")
|
||||
)
|
||||
|
||||
# Restricted event, only erneso users can see it
|
||||
if not self.request.user.is_authenticated and not event.calendrier:
|
||||
return redirect(reverse("calendrier:home"))
|
||||
|
||||
# Count the number of occurences of each instrument
|
||||
instrument_count = defaultdict(lambda: (0, 0, [], [], []))
|
||||
for participant in participants:
|
||||
instru = participant.participant.instru
|
||||
if instru == "Autre":
|
||||
instru = participant.participant.instru_autre
|
||||
|
||||
sure, maybe, namesoui, namespe, namesnon = instrument_count[instru]
|
||||
|
||||
if participant.reponse == "oui":
|
||||
|
||||
namesoui += [participant.participant.get_doodlename()]
|
||||
instrument_count[instru] = (
|
||||
sure + 1,
|
||||
maybe,
|
||||
namesoui,
|
||||
namespe,
|
||||
namesnon,
|
||||
)
|
||||
elif participant.reponse == "pe":
|
||||
namespe += [participant.participant.get_doodlename()]
|
||||
instrument_count[instru] = (
|
||||
sure,
|
||||
maybe + 1,
|
||||
namesoui,
|
||||
namespe,
|
||||
namesnon,
|
||||
)
|
||||
else:
|
||||
namesnon += [participant.participant.get_doodlename()]
|
||||
instrument_count[instru] = (sure, maybe, namesoui,
|
||||
namespe, namesnon)
|
||||
|
||||
instrument_count = [
|
||||
(instrument, sure, maybe, namesoui, namespe, namesnon)
|
||||
for instrument, (
|
||||
sure,
|
||||
maybe,
|
||||
namesoui,
|
||||
namespe,
|
||||
namesnon,
|
||||
) in instrument_count.items()
|
||||
]
|
||||
|
||||
context["event"] = event
|
||||
context["instrument_count"] = instrument_count
|
||||
context["participants"] = participants
|
||||
context["nboui"] = len(participants.filter(reponse="oui"))
|
||||
context["nbpe"] = len(participants.filter(reponse="pe"))
|
||||
context["nbnon"] = len(participants.filter(reponse="non"))
|
||||
context["multi_instrumentistes"] = multi_instrumentistes
|
||||
return context
|
||||
|
||||
|
||||
class ChangeName(LoginRequiredMixin, TemplateView):
|
||||
form_class = ChangeDoodleName
|
||||
template_name = "calendrier/changename.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = self.form_class(instance=self.request.user)
|
||||
context["id"] = self.kwargs['id']
|
||||
return context
|
||||
|
||||
@login_required
|
||||
def changename(request,id):
|
||||
if request.method == 'POST':
|
||||
def post(self, request, *args, **kwargs):
|
||||
success = False
|
||||
requbis = request.POST.copy()
|
||||
form = ChangeDoodleName(requbis, instance=request.user)
|
||||
form = self.form_class(requbis, instance=request.user)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
success = True
|
||||
return redirect('calendrier:view-event',id=id)
|
||||
else:
|
||||
form = ChangeDoodleName(instance=request.user)
|
||||
return render(request, 'calendrier/changename.html',locals())
|
||||
return redirect("calendrier:view-event", id=self.kwargs['id'])
|
||||
else:
|
||||
context = self.get_context_data()
|
||||
context['success'] = success
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
@chef_required
|
||||
def create_event(request):
|
||||
if request.method == "POST":
|
||||
form = EventForm(request.POST)
|
||||
class CreateEvent(LoginRequiredMixin, TemplateView):
|
||||
form_class = EventForm
|
||||
template_name = "calendrier/create.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = self.form_class()
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
if form.is_valid():
|
||||
temp = True
|
||||
while temp:
|
||||
code = generer()
|
||||
try:
|
||||
Event.objects.get(slug=code)
|
||||
except:
|
||||
except Event.DoesNotExist:
|
||||
temp = False
|
||||
nom = form.cleaned_data["nom"]
|
||||
date = form.cleaned_data["date"]
|
||||
date = date.strftime('%d/%m/%Y')
|
||||
debut = form.cleaned_data["debut"]
|
||||
date = date.strftime("%d/%m/%Y")
|
||||
obj = form.save(commit=False)
|
||||
obj.slug = code
|
||||
obj.save()
|
||||
id = obj.id
|
||||
envoi = True
|
||||
return redirect('calendrier:view-event',id=id)
|
||||
|
||||
else:
|
||||
form = EventForm()
|
||||
|
||||
return render(request, "calendrier/create.html", locals())
|
||||
return redirect("calendrier:view-event", id=id)
|
||||
else:
|
||||
context = self.get_context_data()
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class ReponseEvent(LoginRequiredMixin, TemplateView):
|
||||
form_class = ParticipantsForm
|
||||
template_name = "calendrier/reponse.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = self.form_class()
|
||||
context['ev'] = get_object_or_404(Event, id=self.kwargs['id'])
|
||||
context['id'] = self.kwargs['id']
|
||||
return context
|
||||
|
||||
@login_required
|
||||
def reponse(request, id):
|
||||
part = request.user.profile
|
||||
ev = get_object_or_404(Event, id=id)
|
||||
if request.method == "POST":
|
||||
form = ParticipantsForm(request.POST)
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
ev = get_object_or_404(Event, id=self.kwargs['id'])
|
||||
part = request.user.profile
|
||||
if form.is_valid():
|
||||
try:
|
||||
p = Participants.objects.get(event=ev, participant=part)
|
||||
|
@ -222,43 +317,33 @@ def reponse(request, id):
|
|||
obj.event = ev
|
||||
obj.participant = part
|
||||
obj.save()
|
||||
envoi = True
|
||||
return redirect('calendrier:view-event',id=id)
|
||||
else:
|
||||
form = ParticipantsForm()
|
||||
return render(request, "calendrier/reponse.html", locals())
|
||||
return redirect("calendrier:view-event", id=self.kwargs['id'])
|
||||
else:
|
||||
context = self.get_context_data()
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
|
||||
|
||||
class EventUpdate(UpdateView):
|
||||
class EventUpdate(ChefRequiredMixin, UpdateView):
|
||||
model = Event
|
||||
template_name = "calendrier/update.html"
|
||||
form_class = ModifEventForm
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(EventUpdate, self).get_context_data(**kwargs)
|
||||
ctx['id'] = self.get_object().id
|
||||
ctx["id"] = self.get_object().id
|
||||
return ctx
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('calendrier:view-event', kwargs={'id' : self.get_object().id})
|
||||
|
||||
@method_decorator(chef_required)
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super(EventUpdate, self).dispatch(*args, **kwargs)
|
||||
return reverse("calendrier:view-event",
|
||||
kwargs={"id": self.get_object().id})
|
||||
|
||||
|
||||
class EventDelete(DeleteView):
|
||||
class EventDelete(ChefRequiredMixin, DeleteView):
|
||||
model = Event
|
||||
template_name = "calendrier/delete.html"
|
||||
success_url = reverse_lazy("calendrier:home")
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(EventDelete, self).get_context_data(**kwargs)
|
||||
ctx['id'] = self.get_object().id
|
||||
ctx["id"] = self.get_object().id
|
||||
return ctx
|
||||
|
||||
@method_decorator(chef_required)
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super(EventDelete,self).dispatch(*args, **kwargs)
|
||||
|
|
|
@ -6,12 +6,11 @@ les permissions.
|
|||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth.models import User, Group, Permission
|
||||
from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib.auth.models import Group, Permission, User
|
||||
|
||||
from gestion.models import ErnestoUser, VideoGallery, Photo
|
||||
from actu.models import Actu
|
||||
|
||||
from gestion.models import ErnestoUser, Photo, VideoGallery
|
||||
|
||||
|
||||
class UserProfileInline(admin.StackedInline):
|
||||
|
@ -112,6 +111,7 @@ class UserProfileAdmin(UserAdmin):
|
|||
user.groups.add(chef_group)
|
||||
user.save()
|
||||
|
||||
|
||||
admin.site.unregister(User)
|
||||
admin.site.register(User, UserProfileAdmin)
|
||||
admin.site.register(VideoGallery)
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class GestionConfig(AppConfig):
|
||||
name = 'gestion'
|
||||
name = "gestion"
|
||||
|
|
|
@ -1,47 +1,71 @@
|
|||
from django import forms
|
||||
from gestion.models import ErnestoUser
|
||||
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
|
||||
from django.contrib.auth.tokens import default_token_generator
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
|
||||
class RegistrationFormUser(UserCreationForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('username', 'first_name', 'last_name', 'password1',
|
||||
'password2', 'email',)
|
||||
fields = (
|
||||
"username",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"password1",
|
||||
"password2",
|
||||
"email",
|
||||
)
|
||||
|
||||
|
||||
class ChangeFormUser(UserChangeForm):
|
||||
password = None
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ('first_name', 'last_name', 'email',)
|
||||
|
||||
fields = (
|
||||
"first_name",
|
||||
"last_name",
|
||||
"email",
|
||||
)
|
||||
|
||||
|
||||
class ChangeMembreForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
cleaned_data = super(ChangeMembreForm, self).clean()
|
||||
instru=cleaned_data.get("instru")
|
||||
instru = cleaned_data.get("instru")
|
||||
instru_autre = cleaned_data.get("instru_autre")
|
||||
if (instru == "Autre") and not (instru_autre):
|
||||
raise forms.ValidationError(_("Préçisez quel autre instrument"))
|
||||
multi_instru=cleaned_data.get("multi_instrumentiste")
|
||||
multi_instru = cleaned_data.get("multi_instrumentiste")
|
||||
instru_bonus = cleaned_data.get("instru_bonus")
|
||||
if (multi_instru == "Oui") and not (instru_bonus):
|
||||
raise forms.ValidationError(_("Préçisez quel·s instrument·s supplémentaire·s vous pouvez jouer"))
|
||||
raise forms.ValidationError(
|
||||
_("Préçisez quel·s instrument·s supplémentaire·s vous pouvez jouer")
|
||||
)
|
||||
return cleaned_data
|
||||
|
||||
class Meta:
|
||||
model = ErnestoUser
|
||||
fields = ("phone", "instru","instru_autre","multi_instrumentiste","instru_bonus")
|
||||
fields = (
|
||||
"phone",
|
||||
"instru",
|
||||
"instru_autre",
|
||||
"multi_instrumentiste",
|
||||
"instru_bonus",
|
||||
)
|
||||
|
||||
|
||||
class InscriptionMembreForm(ChangeMembreForm):
|
||||
validation = forms.CharField(max_length=100, widget=forms.PasswordInput)
|
||||
|
||||
class Meta:
|
||||
model = ErnestoUser
|
||||
fields = ("phone", "instru","instru_autre",'multi_instrumentiste',
|
||||
'instru_bonus' )
|
||||
fields = (
|
||||
"phone",
|
||||
"instru",
|
||||
"instru_autre",
|
||||
"multi_instrumentiste",
|
||||
"instru_bonus",
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -10,28 +10,64 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ErnestoUser',
|
||||
name="ErnestoUser",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('is_ernesto', models.BooleanField(verbose_name="Membre de l'Ernestophone", default=True)),
|
||||
('is_chef', models.BooleanField(verbose_name='Chef Fanfare', default=False)),
|
||||
('phone', models.CharField(blank=True, max_length=20, verbose_name='Téléphone')),
|
||||
('instru', models.CharField(blank=True, max_length=40, verbose_name='Instrument joué')),
|
||||
('slug', models.CharField(max_length=7, editable=False, unique=True)),
|
||||
('doodlename', models.CharField(blank=True, max_length=30, verbose_name='Nom pour le doodle')),
|
||||
('mails', models.BooleanField(verbose_name='Recevoir les mails', default=True)),
|
||||
(
|
||||
'user',
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_ernesto",
|
||||
models.BooleanField(
|
||||
verbose_name="Membre de l'Ernestophone", default=True
|
||||
),
|
||||
),
|
||||
(
|
||||
"is_chef",
|
||||
models.BooleanField(verbose_name="Chef Fanfare", default=False),
|
||||
),
|
||||
(
|
||||
"phone",
|
||||
models.CharField(
|
||||
blank=True, max_length=20, verbose_name="Téléphone"
|
||||
),
|
||||
),
|
||||
(
|
||||
"instru",
|
||||
models.CharField(
|
||||
blank=True, max_length=40, verbose_name="Instrument joué"
|
||||
),
|
||||
),
|
||||
("slug", models.CharField(max_length=7, editable=False, unique=True)),
|
||||
(
|
||||
"doodlename",
|
||||
models.CharField(
|
||||
blank=True, max_length=30, verbose_name="Nom pour le doodle"
|
||||
),
|
||||
),
|
||||
(
|
||||
"mails",
|
||||
models.BooleanField(
|
||||
verbose_name="Recevoir les mails", default=True
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.OneToOneField(
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='profile'
|
||||
)
|
||||
related_name="profile",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Profil Ernestophoniste',
|
||||
'verbose_name_plural': 'Profil Ernestophoniste',
|
||||
"verbose_name": "Profil Ernestophoniste",
|
||||
"verbose_name_plural": "Profil Ernestophoniste",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,80 +7,157 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestion', '0001_initial'),
|
||||
("gestion", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='VideoGallery',
|
||||
name="VideoGallery",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=127)),
|
||||
('order', models.IntegerField(verbose_name='ordre')),
|
||||
('url', models.URLField()),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=127)),
|
||||
("order", models.IntegerField(verbose_name="ordre")),
|
||||
("url", models.URLField()),
|
||||
],
|
||||
options={
|
||||
'verbose_name_plural': 'Videos',
|
||||
'verbose_name': 'Video',
|
||||
"verbose_name_plural": "Videos",
|
||||
"verbose_name": "Video",
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='ernestouser',
|
||||
name='mails',
|
||||
model_name="ernestouser",
|
||||
name="mails",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='instru_autre',
|
||||
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Lequel ?'),
|
||||
model_name="ernestouser",
|
||||
name="instru_autre",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=100, null=True, verbose_name="Lequel ?"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='instru_bonus',
|
||||
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Le·s·quel·s ?'),
|
||||
model_name="ernestouser",
|
||||
name="instru_bonus",
|
||||
field=models.CharField(
|
||||
blank=True, max_length=100, null=True, verbose_name="Le·s·quel·s ?"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='instru_trombonoscope',
|
||||
field=models.CharField(blank=True, max_length=30, verbose_name='Instrument affiché sur le trombonoscope'),
|
||||
model_name="ernestouser",
|
||||
name="instru_trombonoscope",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
max_length=30,
|
||||
verbose_name="Instrument affiché sur le trombonoscope",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='multi_instrumentiste',
|
||||
field=models.CharField(choices=[('Non', 'Non'), ('Oui', 'Oui')], default='Non', help_text='Seulement si tu connais les partitions par coeur', max_length=3, verbose_name="Je suis capable de jouer d'un autre instrument en manche :"),
|
||||
model_name="ernestouser",
|
||||
name="multi_instrumentiste",
|
||||
field=models.CharField(
|
||||
choices=[("Non", "Non"), ("Oui", "Oui")],
|
||||
default="Non",
|
||||
help_text="Seulement si tu connais les partitions par coeur",
|
||||
max_length=3,
|
||||
verbose_name="Je suis capable de jouer d'un autre instrument en manche :",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='nom_trombonoscope',
|
||||
field=models.CharField(blank=True, max_length=30, verbose_name='Nom affiché sur le trombonoscope'),
|
||||
model_name="ernestouser",
|
||||
name="nom_trombonoscope",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
max_length=30,
|
||||
verbose_name="Nom affiché sur le trombonoscope",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='trombonoscope',
|
||||
field=models.CharField(choices=[('non', 'Non'), ('o_a', 'Oui en tant que fanfaron actuel'), ('o_v', 'Oui en tant que vie·ille·ux')], default='non', max_length=3, null=True, verbose_name='Je souhaite apparaitre dans le trombonoscope :'),
|
||||
model_name="ernestouser",
|
||||
name="trombonoscope",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("non", "Non"),
|
||||
("o_a", "Oui en tant que fanfaron actuel"),
|
||||
("o_v", "Oui en tant que vie·ille·ux"),
|
||||
],
|
||||
default="non",
|
||||
max_length=3,
|
||||
null=True,
|
||||
verbose_name="Je souhaite apparaitre dans le trombonoscope :",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='trombonoscope_colors',
|
||||
field=models.CharField(choices=[('#e4522f#ffffff', 'Orange et Blanc'), ('#ffffff#000000', 'Blanc et Noir'), ('#A8107C#000000', 'Rose et Noir'), ('#10A4A8#ffffff', 'Bleu et Blanc'), ('#26A810#000000', 'Vert et Noir'), ('#A81026#ffffff', 'Rouge et Blanc'), ('#E3E54C#000000', 'Jaune et Noir'), ('autre', 'Autre')], default='OrangeBlanc', max_length=40, verbose_name='Couleur du profil'),
|
||||
model_name="ernestouser",
|
||||
name="trombonoscope_colors",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("#e4522f#ffffff", "Orange et Blanc"),
|
||||
("#ffffff#000000", "Blanc et Noir"),
|
||||
("#A8107C#000000", "Rose et Noir"),
|
||||
("#10A4A8#ffffff", "Bleu et Blanc"),
|
||||
("#26A810#000000", "Vert et Noir"),
|
||||
("#A81026#ffffff", "Rouge et Blanc"),
|
||||
("#E3E54C#000000", "Jaune et Noir"),
|
||||
("autre", "Autre"),
|
||||
],
|
||||
default="OrangeBlanc",
|
||||
max_length=40,
|
||||
verbose_name="Couleur du profil",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='trombonoscope_fond',
|
||||
field=colorful.fields.RGBColorField(default='#e4522f', verbose_name='Couleur de fond du profil'),
|
||||
model_name="ernestouser",
|
||||
name="trombonoscope_fond",
|
||||
field=colorful.fields.RGBColorField(
|
||||
default="#e4522f", verbose_name="Couleur de fond du profil"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ernestouser',
|
||||
name='trombonoscope_texte',
|
||||
field=colorful.fields.RGBColorField(default='#ffffff', verbose_name='Couleur du texte du profil'),
|
||||
model_name="ernestouser",
|
||||
name="trombonoscope_texte",
|
||||
field=colorful.fields.RGBColorField(
|
||||
default="#ffffff", verbose_name="Couleur du texte du profil"
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ernestouser',
|
||||
name='instru',
|
||||
field=models.CharField(choices=[('Clarinette', 'Clarinette'), ('Euphonium', 'Euphonium'), ('Percussion', 'Percussion'), ('Piccolo', 'Piccolo'), ('Saxophone Alto', 'Saxophone Alto'), ('Saxophone Ténor', 'Saxophone Ténor'), ('Saxophone Baryton', 'Saxophone Baryton'), ('Souba', 'Souba'), ('Trombone', 'Trombone'), ('Trompette', 'Trompette'), ('Autre', 'Autre'), ('ne sais pas', 'Je ne sais pas encore')], default='ne sais pas', max_length=40, verbose_name='Instrument joué'),
|
||||
model_name="ernestouser",
|
||||
name="instru",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("Clarinette", "Clarinette"),
|
||||
("Euphonium", "Euphonium"),
|
||||
("Percussion", "Percussion"),
|
||||
("Piccolo", "Piccolo"),
|
||||
("Saxophone Alto", "Saxophone Alto"),
|
||||
("Saxophone Ténor", "Saxophone Ténor"),
|
||||
("Saxophone Baryton", "Saxophone Baryton"),
|
||||
("Souba", "Souba"),
|
||||
("Trombone", "Trombone"),
|
||||
("Trompette", "Trompette"),
|
||||
("Autre", "Autre"),
|
||||
("ne sais pas", "Je ne sais pas encore"),
|
||||
],
|
||||
default="ne sais pas",
|
||||
max_length=40,
|
||||
verbose_name="Instrument joué",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ernestouser',
|
||||
name='phone',
|
||||
field=models.CharField(blank=True, help_text='seulement visible par les chef·fe·s', max_length=20, verbose_name='Téléphone'),
|
||||
model_name="ernestouser",
|
||||
name="phone",
|
||||
field=models.CharField(
|
||||
blank=True,
|
||||
help_text="seulement visible par les chef·fe·s",
|
||||
max_length=20,
|
||||
verbose_name="Téléphone",
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -2,30 +2,84 @@
|
|||
|
||||
import colorful.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import gestion.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestion', '0002_auto_20200908_2222'),
|
||||
("gestion", "0002_auto_20200908_2222"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Photo',
|
||||
name="Photo",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=127)),
|
||||
('cat', models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('n', "N'apparait pas")], default='n', max_length=127)),
|
||||
('auteur', models.CharField(blank=True, max_length=127, null=True, verbose_name="Auteur de l'image")),
|
||||
('url', models.URLField(blank=True, null=True, verbose_name="Lien vers le site de l'auteur")),
|
||||
('color', colorful.fields.RGBColorField(default='#ffffff', verbose_name="Couleur du nom de l'auteur")),
|
||||
('image', models.ImageField(default=None, upload_to='deco', validators=[gestion.models.Photo.validate_image])),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=127)),
|
||||
(
|
||||
"cat",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("home_join", "Rejoignez nous"),
|
||||
("home_contact", "Nous Contacter"),
|
||||
("home_rep", "Répertoire de l'acceuil"),
|
||||
("login", "Connexion"),
|
||||
("change_membre", "Modification du profil"),
|
||||
("inscription_membre", "Inscription"),
|
||||
("home", "Calendrier connecté"),
|
||||
("liste", "Agenda public"),
|
||||
("part", "Répertoire"),
|
||||
("n", "N'apparait pas"),
|
||||
],
|
||||
default="n",
|
||||
max_length=127,
|
||||
),
|
||||
),
|
||||
(
|
||||
"auteur",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=127,
|
||||
null=True,
|
||||
verbose_name="Auteur de l'image",
|
||||
),
|
||||
),
|
||||
(
|
||||
"url",
|
||||
models.URLField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Lien vers le site de l'auteur",
|
||||
),
|
||||
),
|
||||
(
|
||||
"color",
|
||||
colorful.fields.RGBColorField(
|
||||
default="#ffffff", verbose_name="Couleur du nom de l'auteur"
|
||||
),
|
||||
),
|
||||
(
|
||||
"image",
|
||||
models.ImageField(
|
||||
default=None,
|
||||
upload_to="deco",
|
||||
validators=[gestion.models.Photo.validate_image],
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Photo',
|
||||
'verbose_name_plural': 'Photos',
|
||||
"verbose_name": "Photo",
|
||||
"verbose_name_plural": "Photos",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,29 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestion', '0003_photo'),
|
||||
("gestion", "0003_photo"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='photo',
|
||||
name='cat',
|
||||
field=models.CharField(choices=[('home_join', 'Rejoignez nous'), ('home_contact', 'Nous Contacter'), ('home_rep', "Répertoire de l'acceuil"), ('login', 'Connexion'), ('change_membre', 'Modification du profil'), ('inscription_membre', 'Inscription'), ('home', 'Calendrier connecté'), ('liste', 'Agenda public'), ('part', 'Répertoire'), ('instru', 'Instruments'), ('n', "N'apparait pas")], default='n', max_length=127),
|
||||
model_name="photo",
|
||||
name="cat",
|
||||
field=models.CharField(
|
||||
choices=[
|
||||
("home_join", "Rejoignez nous"),
|
||||
("home_contact", "Nous Contacter"),
|
||||
("home_rep", "Répertoire de l'acceuil"),
|
||||
("login", "Connexion"),
|
||||
("change_membre", "Modification du profil"),
|
||||
("inscription_membre", "Inscription"),
|
||||
("home", "Calendrier connecté"),
|
||||
("liste", "Agenda public"),
|
||||
("part", "Répertoire"),
|
||||
("instru", "Instruments"),
|
||||
("n", "N'apparait pas"),
|
||||
],
|
||||
default="n",
|
||||
max_length=127,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,38 +1,48 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models
|
||||
from colorful.fields import RGBColorField
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Photo(models.Model):
|
||||
PHOTO_PLACEMENT = (
|
||||
('home_join', _("Rejoignez nous")),
|
||||
('home_contact', _("Nous Contacter")),
|
||||
('home_rep', _("Répertoire de l'acceuil")),
|
||||
('login', _('Connexion')),
|
||||
('change_membre', _('Modification du profil')),
|
||||
('inscription_membre', _('Inscription')),
|
||||
('home', _('Calendrier connecté')),
|
||||
('liste', _('Agenda public')),
|
||||
('part', _('Répertoire')),
|
||||
('instru', _('Instruments')),
|
||||
('n',_("N'apparait pas"))
|
||||
)
|
||||
("home_join", _("Rejoignez nous")),
|
||||
("home_contact", _("Nous Contacter")),
|
||||
("home_rep", _("Répertoire de l'acceuil")),
|
||||
("login", _("Connexion")),
|
||||
("change_membre", _("Modification du profil")),
|
||||
("inscription_membre", _("Inscription")),
|
||||
("home", _("Calendrier connecté")),
|
||||
("liste", _("Agenda public")),
|
||||
("part", _("Répertoire")),
|
||||
("instru", _("Instruments")),
|
||||
("n", _("N'apparait pas")),
|
||||
)
|
||||
|
||||
def validate_image(fieldfile_obj):
|
||||
filesize = fieldfile_obj.file.size
|
||||
megabyte_limit = 1.0
|
||||
if filesize > megabyte_limit*1024*1024:
|
||||
raise ValidationError("Max file size is %sMB" % str(megabyte_limit))
|
||||
mb_limit = 1.0
|
||||
if filesize > mb_limit * 1024 * 1024:
|
||||
raise ValidationError("La taille max est %sMB" % str(mb_limit))
|
||||
|
||||
name = models.CharField(max_length=127)
|
||||
cat = models.CharField(max_length = 127,choices = PHOTO_PLACEMENT,default='n')
|
||||
auteur = models.CharField(max_length=127,verbose_name=_("Auteur de l'image"),null=True,blank=True)
|
||||
url = models.URLField(verbose_name=_("Lien vers le site de l'auteur"),null=True,blank=True)
|
||||
color = RGBColorField(_("Couleur du nom de l'auteur"),default='#ffffff')
|
||||
image = models.ImageField(upload_to='deco',default=None,validators=[validate_image])
|
||||
cat = models.CharField(max_length=127, choices=PHOTO_PLACEMENT,
|
||||
default="n")
|
||||
auteur = models.CharField(
|
||||
max_length=127, verbose_name=_("Auteur de l'image"), null=True,
|
||||
blank=True
|
||||
)
|
||||
url = models.URLField(
|
||||
verbose_name=_("Lien vers le site de l'auteur"), null=True, blank=True
|
||||
)
|
||||
color = RGBColorField(_("Couleur du nom de l'auteur"), default="#ffffff")
|
||||
image = models.ImageField(
|
||||
upload_to="deco", default=None, validators=[validate_image]
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
@ -42,57 +52,101 @@ class Photo(models.Model):
|
|||
|
||||
|
||||
class ErnestoUser(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
|
||||
is_ernesto = models.BooleanField(_("Membre de l'Ernestophone"), default=True)
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE,
|
||||
related_name="profile")
|
||||
is_ernesto = models.BooleanField(_("Membre de l'Ernestophone"),
|
||||
default=True)
|
||||
is_chef = models.BooleanField(_("Chef Fanfare"), default=False)
|
||||
phone = models.CharField(_("Téléphone"), max_length=20, blank=True ,help_text= _("seulement visible par les chef·fe·s"))
|
||||
phone = models.CharField(
|
||||
_("Téléphone"),
|
||||
max_length=20,
|
||||
blank=True,
|
||||
help_text=_("seulement visible par les chef·fe·s"),
|
||||
)
|
||||
|
||||
INSTRU_CHOICES = [
|
||||
('Clarinette', _('Clarinette')),
|
||||
('Euphonium', _('Euphonium')),
|
||||
('Percussion', _('Percussion')),
|
||||
('Piccolo', _('Piccolo')),
|
||||
('Saxophone Alto', _('Saxophone Alto')),
|
||||
('Saxophone Ténor', _('Saxophone Ténor')),
|
||||
('Saxophone Baryton', _('Saxophone Baryton')),
|
||||
('Souba', _('Souba')),
|
||||
('Trombone', _('Trombone')),
|
||||
('Trompette', _('Trompette')),
|
||||
('Autre', _('Autre')),
|
||||
('ne sais pas', _('Je ne sais pas encore')),
|
||||
("Clarinette", _("Clarinette")),
|
||||
("Euphonium", _("Euphonium")),
|
||||
("Percussion", _("Percussion")),
|
||||
("Piccolo", _("Piccolo")),
|
||||
("Saxophone Alto", _("Saxophone Alto")),
|
||||
("Saxophone Ténor", _("Saxophone Ténor")),
|
||||
("Saxophone Baryton", _("Saxophone Baryton")),
|
||||
("Souba", _("Souba")),
|
||||
("Trombone", _("Trombone")),
|
||||
("Trompette", _("Trompette")),
|
||||
("Autre", _("Autre")),
|
||||
("ne sais pas", _("Je ne sais pas encore")),
|
||||
]
|
||||
|
||||
COLORS_CHOICES = [
|
||||
('#e4522f#ffffff', _('Orange et Blanc')),
|
||||
('#ffffff#000000', _('Blanc et Noir')),
|
||||
('#A8107C#000000', _('Rose et Noir')),
|
||||
('#10A4A8#ffffff', _('Bleu et Blanc')),
|
||||
('#26A810#000000', _('Vert et Noir')),
|
||||
('#A81026#ffffff', _('Rouge et Blanc')),
|
||||
('#E3E54C#000000', _('Jaune et Noir')),
|
||||
('autre',_('Autre')),
|
||||
("#e4522f#ffffff", _("Orange et Blanc")),
|
||||
("#ffffff#000000", _("Blanc et Noir")),
|
||||
("#A8107C#000000", _("Rose et Noir")),
|
||||
("#10A4A8#ffffff", _("Bleu et Blanc")),
|
||||
("#26A810#000000", _("Vert et Noir")),
|
||||
("#A81026#ffffff", _("Rouge et Blanc")),
|
||||
("#E3E54C#000000", _("Jaune et Noir")),
|
||||
("autre", _("Autre")),
|
||||
]
|
||||
|
||||
]
|
||||
|
||||
instru = models.CharField(_("Instrument joué"), max_length=40, blank=False,choices=INSTRU_CHOICES,default='ne sais pas')
|
||||
instru_autre = models.CharField(_("Lequel ?"),null=True,max_length=100,blank=True)
|
||||
instru = models.CharField(
|
||||
_("Instrument joué"),
|
||||
max_length=40,
|
||||
blank=False,
|
||||
choices=INSTRU_CHOICES,
|
||||
default="ne sais pas",
|
||||
)
|
||||
instru_autre = models.CharField(
|
||||
_("Lequel ?"), null=True, max_length=100, blank=True
|
||||
)
|
||||
slug = models.CharField(max_length=7, editable=False, unique=True)
|
||||
doodlename = models.CharField(_("Nom pour le doodle"), max_length=30,
|
||||
blank=True)
|
||||
|
||||
trombonoscope = models.CharField(_('Je souhaite apparaitre dans le trombonoscope :'),max_length=3,blank=False,null=True,choices=[('non',_('Non')),('o_a',_('Oui en tant que fanfaron actuel')),('o_v',_('Oui en tant que vie·ille·ux'))],default='non')
|
||||
instru_trombonoscope = models.CharField(_("Instrument affiché sur le trombonoscope"), max_length=30,
|
||||
blank=True)
|
||||
nom_trombonoscope = models.CharField(_("Nom affiché sur le trombonoscope"), max_length=30,
|
||||
blank=True)
|
||||
trombonoscope_colors = models.CharField(_("Couleur du profil"), max_length=40, blank=False,choices=COLORS_CHOICES,default='OrangeBlanc')
|
||||
trombonoscope_fond = RGBColorField(_("Couleur de fond du profil"),default='#e4522f')
|
||||
trombonoscope_texte = RGBColorField(_("Couleur du texte du profil"),default='#ffffff')
|
||||
|
||||
multi_instrumentiste = models.CharField(_("Je suis capable de jouer d'un autre instrument en manche :"),default='Non',null=False,max_length=3,choices=[('Non',_('Non')),('Oui',_('Oui'))],help_text= _("Seulement si tu connais les partitions par coeur"))
|
||||
instru_bonus = models.CharField(_("Le·s·quel·s ?"),null=True,max_length=100,blank=True)
|
||||
|
||||
trombonoscope = models.CharField(
|
||||
_("Je souhaite apparaitre dans le trombonoscope:"),
|
||||
max_length=3,
|
||||
blank=False,
|
||||
null=True,
|
||||
choices=[
|
||||
("non", _("Non")),
|
||||
("o_a", _("Oui en tant que fanfaron actuel")),
|
||||
("o_v", _("Oui en tant que vie·ille·ux")),
|
||||
],
|
||||
default="non",
|
||||
)
|
||||
instru_trombonoscope = models.CharField(
|
||||
_("Instrument affiché sur le trombonoscope"), max_length=30, blank=True
|
||||
)
|
||||
nom_trombonoscope = models.CharField(
|
||||
_("Nom affiché sur le trombonoscope"), max_length=30, blank=True
|
||||
)
|
||||
trombonoscope_colors = models.CharField(
|
||||
_("Couleur du profil"),
|
||||
max_length=40,
|
||||
blank=False,
|
||||
choices=COLORS_CHOICES,
|
||||
default="OrangeBlanc",
|
||||
)
|
||||
trombonoscope_fond = RGBColorField(
|
||||
_("Couleur de fond du profil"), default="#e4522f"
|
||||
)
|
||||
trombonoscope_texte = RGBColorField(
|
||||
_("Couleur du texte du profil"), default="#ffffff"
|
||||
)
|
||||
|
||||
multi_instrumentiste = models.CharField(
|
||||
_("Je suis capable de jouer d'un autre instrument en manche :"),
|
||||
default="Non",
|
||||
null=False,
|
||||
max_length=3,
|
||||
choices=[("Non", _("Non")), ("Oui", _("Oui"))],
|
||||
help_text=_("Seulement si tu connais les partitions par coeur"),
|
||||
)
|
||||
instru_bonus = models.CharField(
|
||||
_("Le·s·quel·s ?"), null=True, max_length=100, blank=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Profil Ernestophoniste")
|
||||
|
|
|
@ -33,13 +33,15 @@
|
|||
<!-- Nav -->
|
||||
<nav id="menu">
|
||||
<ul class="links">
|
||||
<li><p></p></li>
|
||||
|
||||
<li>{% ifequal current_language "fr" %}
|
||||
<a href="{% changelang "en" %}" >English<span class="image right"><img src="{% static "images/en_flag.jpg" %}"></span></a>
|
||||
{% else %}
|
||||
<a href="{% changelang "fr" %}">Français<span class="image right"><img src="{% static "images/fr_flag.jpg" %}"></span></a>
|
||||
{% endifequal %}</li>
|
||||
|
||||
{% if not user.is_authenticated %}
|
||||
|
||||
<li><a href="{% url 'home' %}">{% trans "Accueil" %}</a></li>
|
||||
<li><a href="{% url 'calendrier:liste' %}">{% trans "Agenda" %}</a></li>
|
||||
{% else %}
|
||||
|
@ -47,24 +49,38 @@
|
|||
{% endif %}
|
||||
<li><a href="{% url 'partitions:liste' %}">{% trans "Répertoire" %}</a></li>
|
||||
{% if user.is_authenticated %}
|
||||
<li><a href="{% url 'trombonoscope:view' %}">{% trans "Trombonoscope" %}</a></li>
|
||||
<li><a href="{% url 'instruments:liste' %}">{% trans "Instruments" %}</a></li>
|
||||
<li><a href="https://photos.cof.ens.fr/index.php/Clubs-du-COF/L'Ernestophone" target="_blank">{% trans "Galerie Photo" %}</a></li>
|
||||
<li><a href="{% url 'instruments:liste' %}">{% trans "Instruments" %}</a></li>
|
||||
<li><a href="{% url 'pads:list' %}">{% trans "Pads" %}</a></li>
|
||||
</ul>
|
||||
<h1>{% trans "Social :" %}</h1>
|
||||
<ul class ="links">
|
||||
<li><a href="{% url 'trombonoscope:view' %}">{% trans "Trombonoscope" %}</a></li>
|
||||
<li><a href="https://photos.cof.ens.fr/index.php/Clubs-du-COF/L'Ernestophone" target="_blank">{% trans "Galerie Photo" %}</a></li>
|
||||
</ul>
|
||||
<h1> {% trans "Mon profil :" %}</h1>
|
||||
<ul class = 'links'>
|
||||
<li><a href="{% url 'change_membre' %}">{% trans "Modification du profil" %}</a></li>
|
||||
<li><a href="{% url 'logout' %}">{% trans "Déconnexion" %}</a></li>
|
||||
</ul>
|
||||
|
||||
{% if user.is_superuser or user.profile.is_chef %}
|
||||
</ul>
|
||||
<h1>{% trans "Le pouvoir des chef·fe·s :" %}</h1>
|
||||
<ul class="links">
|
||||
<li><a href="/admin/">{% trans "Administration" %}</a></li>
|
||||
{% if user.profile.is_chef %}
|
||||
<li><a href="{% url 'actu:liste' %}">{% trans "Modifier les actualités" %}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<li><a href="{% url 'change_membre' %}">{% trans "Modification du profil" %}</a></li>
|
||||
<li><a href="{% url 'logout' %}">{% trans "Déconnexion" %}</a></li>
|
||||
|
||||
</ul>
|
||||
{% else %}
|
||||
<li><a href="{% url 'login' %}">{% trans "Se connecter" %}</a></li>
|
||||
<li><a href="{% url 'registration' %}">{% trans "Créer un compte" %}</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
|
||||
|
||||
|
|
|
@ -3,12 +3,13 @@ from django.utils.safestring import mark_safe
|
|||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def autotranslate(current_language, description, description_en):
|
||||
|
||||
if( current_language != "fr" and description_en):
|
||||
if current_language != "fr" and description_en:
|
||||
return mark_safe(description_en)
|
||||
elif(current_language == "fr" and not description):
|
||||
elif current_language == "fr" and not description:
|
||||
return mark_safe(description_en)
|
||||
else:
|
||||
return mark_safe(description)
|
||||
|
|
|
@ -12,7 +12,7 @@ def changelang(context, lang=None, *args, **kwargs):
|
|||
Usage: {% change_lang 'en' %}
|
||||
"""
|
||||
|
||||
path = context['request'].path
|
||||
path = context["request"].path
|
||||
url_parts = resolve(path)
|
||||
|
||||
url = path
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from django.template import Library
|
||||
from math import ceil
|
||||
|
||||
from django.template import Library
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def half_length(liste):
|
||||
try:
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from django import template
|
||||
from datetime import date, timedelta
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def modulo(num, val):
|
||||
return num % val
|
||||
|
|
221
gestion/views.py
221
gestion/views.py
|
@ -1,132 +1,187 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from partitions.models import Category
|
||||
from gestion.forms import ChangeMembreForm, ChangeFormUser,RegistrationFormUser, InscriptionMembreForm
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponseRedirect
|
||||
from gestion.models import ErnestoUser, VideoGallery, Photo
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
from calendrier.forms import ChangeDoodleName
|
||||
from partitions.decorators import chef_required
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
from django.contrib.auth.views import LoginView
|
||||
from django.urls import reverse_lazy
|
||||
from django.shortcuts import render_to_response
|
||||
import string
|
||||
import random
|
||||
import string
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.forms import PasswordChangeForm
|
||||
from django.contrib.auth.views import LoginView
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
from calendrier.forms import ChangeDoodleName
|
||||
from gestion.forms import (ChangeFormUser, ChangeMembreForm,
|
||||
InscriptionMembreForm, RegistrationFormUser)
|
||||
from gestion.models import ErnestoUser, Photo, VideoGallery
|
||||
from partitions.models import Category
|
||||
from django.views.generic import TemplateView
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
def generer(*args):
|
||||
caracteres = string.ascii_letters + string.digits
|
||||
aleatoire = [random.choice(caracteres) for _ in range(6)]
|
||||
return ''.join(aleatoire)
|
||||
aleatoire = [random.choice(caracteres) for i in range(6)]
|
||||
return "".join(aleatoire)
|
||||
|
||||
|
||||
def home(request):
|
||||
if request.user.is_authenticated :
|
||||
return redirect('calendrier:home')
|
||||
categories = Category.objects.filter(name = "Partitions actives").prefetch_related("partitionset_set")
|
||||
videos = VideoGallery.objects.all()
|
||||
photo_rep = Photo.objects.filter(cat='home_rep').order_by('?').first()
|
||||
photo_join = Photo.objects.filter(cat='home_join').order_by('?').first()
|
||||
photo_contact = Photo.objects.filter(cat='home_contact').order_by('?').first()
|
||||
return render_to_response( 'gestion/index.html', {"request":request,"categories": categories,'videos':videos,'photo_rep':photo_rep,'photo_join':photo_join,'photo_contact':photo_contact})
|
||||
class Home(TemplateView):
|
||||
template_name = "gestion/index.html"
|
||||
|
||||
class MyLoginView(LoginView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('calendrier:home')
|
||||
return super(Home, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
template_name = 'gestion/login.html'
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
photo = Photo.objects.filter(cat='login').order_by('?').first()
|
||||
context['photo'] = photo
|
||||
context["categories"] = Category.objects.filter(
|
||||
name="Partitions actives").prefetch_related(
|
||||
"partitionset_set"
|
||||
)
|
||||
context['videos'] = VideoGallery.objects.all()
|
||||
context['photo_rep'] = Photo.objects.filter(
|
||||
cat="home_rep").order_by("?").first()
|
||||
context['photo_join'] = Photo.objects.filter(
|
||||
cat="home_join").order_by("?").first()
|
||||
context['photo_contact'] = Photo.objects.filter(
|
||||
cat="home_contact").order_by("?").first()
|
||||
return context
|
||||
|
||||
|
||||
def thanks(request):
|
||||
class MyLoginView(LoginView):
|
||||
|
||||
return render(request, 'gestion/thanks.html', locals())
|
||||
template_name = "gestion/login.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["photo"] = Photo.objects.filter(
|
||||
cat="login").order_by("?").first()
|
||||
return context
|
||||
|
||||
|
||||
@login_required
|
||||
def changename(request):
|
||||
if request.method == 'POST':
|
||||
class Thanks(TemplateView):
|
||||
template_name = "gestion/thanks.html"
|
||||
|
||||
|
||||
class ChangeName(LoginRequiredMixin, TemplateView):
|
||||
form_class = ChangeDoodleName
|
||||
template_name = "gestion/changename.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = self.form_class(instance=self.request.user)
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
requbis = request.POST.copy()
|
||||
form = ChangeDoodleName(requbis, instance=request.user)
|
||||
form = self.form_class(requbis,
|
||||
instance=request.user)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
success = True
|
||||
return redirect('change_membre')
|
||||
else:
|
||||
form = ChangeDoodleName(instance=request.user)
|
||||
return render(request, 'gestion/changename.html', locals())
|
||||
return redirect("change_membre")
|
||||
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class ChangeMembre(LoginRequiredMixin, TemplateView):
|
||||
comp_form_class = ChangeMembreForm
|
||||
user_form_class = ChangeFormUser
|
||||
template_name = "gestion/change.html"
|
||||
|
||||
@login_required
|
||||
def change_membre(request):
|
||||
photo = Photo.objects.filter(cat='change_membre').order_by('?').first()
|
||||
if request.method == 'POST':
|
||||
comp_form = ChangeMembreForm(request.POST, instance=request.user.profile)
|
||||
user_form = ChangeFormUser(request.POST, instance=request.user)
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
comp_form = self.comp_form_class(instance=self.request.user.profile)
|
||||
user_form = self.user_form_class(instance=self.request.user)
|
||||
context["comp_form"] = comp_form
|
||||
context["user_form"] = user_form
|
||||
context["photo"] = Photo.objects.filter(
|
||||
cat="change_membre").order_by("?").first()
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
success = False
|
||||
comp_form = self.comp_form_class(request.POST,
|
||||
instance=request.user.profile)
|
||||
user_form = self.user_form_class(request.POST, instance=request.user)
|
||||
if user_form.is_valid() and comp_form.is_valid():
|
||||
user_form.save()
|
||||
comp_form.save()
|
||||
success = True
|
||||
return redirect('home')
|
||||
else:
|
||||
comp_form = ChangeMembreForm(instance=request.user.profile)
|
||||
user_form = ChangeFormUser(instance=request.user)
|
||||
return render(request, 'gestion/change.html', locals())
|
||||
|
||||
@login_required
|
||||
def change_password(request):
|
||||
if request.method == 'POST':
|
||||
context = self.get_context_data()
|
||||
context['success'] = success
|
||||
context['comp_form'] = comp_form
|
||||
context['user_form'] = user_form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class ChangePassword(LoginRequiredMixin, TemplateView):
|
||||
form_class = PasswordChangeForm
|
||||
template_name = "gestion/changepasswd.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = self.form_class(self.request.user)
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
requbis = request.POST.copy()
|
||||
form = PasswordChangeForm(request.user, data=requbis)
|
||||
success = False
|
||||
form = self.form_class(request.user, data=requbis)
|
||||
if form.is_valid():
|
||||
|
||||
request.user.profile.photo.delete()
|
||||
form.save()
|
||||
|
||||
success = True
|
||||
|
||||
else:
|
||||
form = PasswordChangeForm(request.user)
|
||||
return render(request, 'gestion/changepasswd.html', locals())
|
||||
context = self.get_context_data()
|
||||
context['success'] = success
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class Inscription(TemplateView):
|
||||
user_form_class = RegistrationFormUser
|
||||
comp_form_class = InscriptionMembreForm
|
||||
template_name = "gestion/registration.html"
|
||||
|
||||
def inscription_membre(request):
|
||||
photo = Photo.objects.filter(cat='inscription_membre').order_by('?').first()
|
||||
if request.method == 'POST':
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['comp_form'] = self.comp_form_class()
|
||||
context['user_form'] = self.user_form_class()
|
||||
context['photo'] = Photo.objects.filter(
|
||||
cat="inscription_membre").order_by("?").first()
|
||||
return context
|
||||
|
||||
user_form = RegistrationFormUser(request.POST)
|
||||
comp_form = InscriptionMembreForm(request.POST)
|
||||
def post(self, request, *args, **kwargs):
|
||||
user_form = self.user_form_class(request.POST)
|
||||
comp_form = self.comp_form_class(request.POST)
|
||||
if user_form.is_valid() and comp_form.is_valid():
|
||||
pseudo = user_form.cleaned_data['username']
|
||||
if not (comp_form.cleaned_data['validation']
|
||||
== settings.ACCOUNT_CREATION_PASS):
|
||||
error = "Le champ Validation ne correspond pas à celui attendu"
|
||||
return render(request, "gestion/registration.html", locals())
|
||||
|
||||
if not (
|
||||
comp_form.cleaned_data["validation"] == settings.ACCOUNT_CREATION_PASS
|
||||
):
|
||||
error = _("Le champ Validation ne correspond pas à celui attendu")
|
||||
context = self.get_context_data()
|
||||
context['user_form'] = user_form
|
||||
context['comp_form'] = comp_form
|
||||
context['error'] = error
|
||||
return render(request, self.template_name, context)
|
||||
member = user_form.save(commit=False)
|
||||
temp = True
|
||||
while temp:
|
||||
code = generer()
|
||||
try:
|
||||
ErnestoUser.objects.get(slug=code)
|
||||
except:
|
||||
except ErnestoUser.DoesNotExist:
|
||||
temp = False
|
||||
member.save()
|
||||
(profile, _) = ErnestoUser.objects.get_or_create(user=member,
|
||||
(profile, k) = ErnestoUser.objects.get_or_create(user=member,
|
||||
slug=code)
|
||||
comp_form = InscriptionMembreForm(request.POST, instance=profile)
|
||||
comp_form = self.comp_form_class(request.POST, instance=profile)
|
||||
obj = comp_form.save(commit=False)
|
||||
obj.slug = code
|
||||
obj.save()
|
||||
envoi = True
|
||||
return redirect('thanks')
|
||||
else:
|
||||
comp_form = InscriptionMembreForm()
|
||||
user_form = RegistrationFormUser()
|
||||
return render(request, 'gestion/registration.html', locals())
|
||||
return redirect("thanks")
|
||||
else:
|
||||
context = self.get_context_data()
|
||||
context['user_form'] = user_form
|
||||
context['comp_form'] = comp_form
|
||||
return render(request, self.template_name, context)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
from .models import Instrument,Reparation
|
||||
|
||||
from .models import Instrument, Reparation
|
||||
|
||||
admin.site.register(Instrument)
|
||||
admin.site.register(Reparation)
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class InstrumentsConfig(AppConfig):
|
||||
name = 'instruments'
|
||||
name = "instruments"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
from django.contrib.auth.decorators import user_passes_test
|
||||
|
||||
|
||||
def is_chef(user):
|
||||
try:
|
||||
profile = user.profile
|
||||
return profile.is_chef
|
||||
except:
|
||||
return False
|
||||
|
||||
chef_required = user_passes_test(lambda u: is_chef(u))
|
|
@ -0,0 +1,27 @@
|
|||
from django import forms
|
||||
|
||||
from .models import Instrument, Reparation
|
||||
|
||||
|
||||
class ChefReparationForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Reparation
|
||||
fields = ("date", "description", "description_en", "prix", "lieux")
|
||||
|
||||
|
||||
class ChefEditInstrumentForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Instrument
|
||||
fields = (
|
||||
"statut",
|
||||
"user",
|
||||
"infos",
|
||||
"type",
|
||||
"owner",
|
||||
"marque",
|
||||
"model",
|
||||
"serial",
|
||||
"annee",
|
||||
"prix",
|
||||
"infos_en",
|
||||
)
|
|
@ -1,56 +1,174 @@
|
|||
# Generated by Django 2.2.17 on 2021-04-01 19:25
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Instrument',
|
||||
name="Instrument",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('model', models.CharField(blank=True, max_length=100, null=True, verbose_name='Modèle')),
|
||||
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
|
||||
('etat', models.CharField(choices=[('Bon état', 'Bon état'), ('Etat moyen', 'Etat moyen'), ('Mauvais état', 'Mauvais état')], default='Bon état', max_length=100)),
|
||||
('marque', models.CharField(blank=True, max_length=100, null=True, verbose_name='Marque')),
|
||||
('serial', models.CharField(blank=True, default=' ', max_length=100, null=True, verbose_name='Numéro de série')),
|
||||
('annee', models.CharField(blank=True, max_length=100, null=True, verbose_name="Année d'achat")),
|
||||
('owner', models.CharField(default='Fanfare', max_length=100, verbose_name='Propriétaire')),
|
||||
('user', models.CharField(blank=True, max_length=100, verbose_name='Utilisateur')),
|
||||
('type', models.CharField(max_length=40, verbose_name='Instrument')),
|
||||
('statut', models.CharField(choices=[('Disponible', 'Disponible'), ('Prêté', 'Prêté')], default='Disponible', max_length=100)),
|
||||
('infos', models.TextField(blank=True, default='', verbose_name='Infos utiles')),
|
||||
('infos_en', models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"model",
|
||||
models.CharField(
|
||||
blank=True, max_length=100, null=True, verbose_name="Modèle"
|
||||
),
|
||||
),
|
||||
(
|
||||
"prix",
|
||||
models.CharField(
|
||||
blank=True, default="", max_length=100, verbose_name="Prix"
|
||||
),
|
||||
),
|
||||
(
|
||||
"etat",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("Bon état", "Bon état"),
|
||||
("Etat moyen", "Etat moyen"),
|
||||
("Mauvais état", "Mauvais état"),
|
||||
],
|
||||
default="Bon état",
|
||||
max_length=100,
|
||||
),
|
||||
),
|
||||
(
|
||||
"marque",
|
||||
models.CharField(
|
||||
blank=True, max_length=100, null=True, verbose_name="Marque"
|
||||
),
|
||||
),
|
||||
(
|
||||
"serial",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=" ",
|
||||
max_length=100,
|
||||
null=True,
|
||||
verbose_name="Numéro de série",
|
||||
),
|
||||
),
|
||||
(
|
||||
"annee",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=100,
|
||||
null=True,
|
||||
verbose_name="Année d'achat",
|
||||
),
|
||||
),
|
||||
(
|
||||
"owner",
|
||||
models.CharField(
|
||||
default="Fanfare", max_length=100, verbose_name="Propriétaire"
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.CharField(
|
||||
blank=True, max_length=100, verbose_name="Utilisateur"
|
||||
),
|
||||
),
|
||||
("type", models.CharField(max_length=40, verbose_name="Instrument")),
|
||||
(
|
||||
"statut",
|
||||
models.CharField(
|
||||
choices=[("Disponible", "Disponible"), ("Prêté", "Prêté")],
|
||||
default="Disponible",
|
||||
max_length=100,
|
||||
),
|
||||
),
|
||||
(
|
||||
"infos",
|
||||
models.TextField(
|
||||
blank=True, default="", verbose_name="Infos utiles"
|
||||
),
|
||||
),
|
||||
(
|
||||
"infos_en",
|
||||
models.TextField(
|
||||
blank=True, default="", verbose_name="Infos utiles en anglais"
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Instrument',
|
||||
'verbose_name_plural': 'Instruments',
|
||||
'ordering': (django.db.models.functions.text.Lower('type'),),
|
||||
"verbose_name": "Instrument",
|
||||
"verbose_name_plural": "Instruments",
|
||||
"ordering": (django.db.models.functions.text.Lower("type"),),
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Reparation',
|
||||
name="Reparation",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date', models.DateField(max_length=100, verbose_name='Date')),
|
||||
('description', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description')),
|
||||
('description_en', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Description en anglais')),
|
||||
('prix', models.CharField(blank=True, default='', max_length=100, verbose_name='Prix')),
|
||||
('lieux', models.CharField(blank=True, default=' ', max_length=100, verbose_name='Lieux')),
|
||||
('instru', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='instruments.Instrument', verbose_name='Instrument')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("date", models.DateField(max_length=100, verbose_name="Date")),
|
||||
(
|
||||
"description",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=" ",
|
||||
max_length=100,
|
||||
verbose_name="Description",
|
||||
),
|
||||
),
|
||||
(
|
||||
"description_en",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
default=" ",
|
||||
max_length=100,
|
||||
verbose_name="Description en anglais",
|
||||
),
|
||||
),
|
||||
(
|
||||
"prix",
|
||||
models.CharField(
|
||||
blank=True, default="", max_length=100, verbose_name="Prix"
|
||||
),
|
||||
),
|
||||
(
|
||||
"lieux",
|
||||
models.CharField(
|
||||
blank=True, default=" ", max_length=100, verbose_name="Lieux"
|
||||
),
|
||||
),
|
||||
(
|
||||
"instru",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="instruments.Instrument",
|
||||
verbose_name="Instrument",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Réparation',
|
||||
'verbose_name_plural': 'Réparations',
|
||||
'ordering': ('date',),
|
||||
"verbose_name": "Réparation",
|
||||
"verbose_name_plural": "Réparations",
|
||||
"ordering": ("date",),
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.db.models.functions import Lower
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
@ -8,37 +5,62 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
class Instrument(models.Model):
|
||||
|
||||
model = models.CharField(_("Modèle"),max_length=100,null=True,blank=True)
|
||||
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
|
||||
etat = models.CharField(max_length=100,default='Bon état',choices = [('Bon état',_('Bon état')),('Etat moyen',_('Etat moyen')),('Mauvais état',_('Mauvais état'))])
|
||||
marque = models.CharField(_("Marque"),max_length=100,null=True,blank=True)
|
||||
serial = models.CharField(_("Numéro de série"),max_length=100,default=' ',null=True,blank=True)
|
||||
annee = models.CharField(_("Année d'achat"),max_length=100,null=True,blank=True)
|
||||
owner = models.CharField(_("Propriétaire"),max_length=100,default='Fanfare')
|
||||
user = models.CharField(_('Utilisateur'),max_length=100,blank=True)
|
||||
model = models.CharField(_("Modèle"), max_length=100, null=True, blank=True)
|
||||
prix = models.CharField(_("Prix"), max_length=100, default="", blank=True)
|
||||
etat = models.CharField(
|
||||
max_length=100,
|
||||
default="Bon état",
|
||||
choices=[
|
||||
("Bon état", _("Bon état")),
|
||||
("Etat moyen", _("Etat moyen")),
|
||||
("Mauvais état", _("Mauvais état")),
|
||||
],
|
||||
)
|
||||
marque = models.CharField(_("Marque"), max_length=100, null=True, blank=True)
|
||||
serial = models.CharField(
|
||||
_("Numéro de série"), max_length=100, default=" ", null=True, blank=True
|
||||
)
|
||||
annee = models.CharField(_("Année d'achat"), max_length=100, null=True, blank=True)
|
||||
owner = models.CharField(_("Propriétaire"), max_length=100, default="Fanfare")
|
||||
user = models.CharField(_("Utilisateur"), max_length=100, blank=True)
|
||||
type = models.CharField(_("Instrument"), max_length=40, blank=False)
|
||||
statut = models.CharField(max_length=100,default='Disponible',choices = [('Disponible',_('Disponible')),('Prêté',_('Prêté'))])
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="")
|
||||
infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="")
|
||||
statut = models.CharField(
|
||||
max_length=100,
|
||||
default="Disponible",
|
||||
choices=[("Disponible", _("Disponible")), ("Prêté", _("Prêté·e"))],
|
||||
)
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True, default="")
|
||||
infos_en = models.TextField(
|
||||
"Infos utiles en anglais", null=False, blank=True, default=""
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.type
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Instrument')
|
||||
verbose_name_plural = _('Instruments')
|
||||
ordering = (Lower('type'),)
|
||||
verbose_name = _("Instrument")
|
||||
verbose_name_plural = _("Instruments")
|
||||
ordering = (Lower("type"),)
|
||||
|
||||
|
||||
class Reparation(models.Model):
|
||||
date = models.DateField(_("Date"),max_length=100)
|
||||
instru = models.ForeignKey("Instrument", on_delete=models.CASCADE,verbose_name=_("Instrument"))
|
||||
description = models.CharField(_("Description"),max_length=100,default=' ',blank=True)
|
||||
description_en = models.CharField(_("Description en anglais"),max_length=100,default=' ',blank=True)
|
||||
prix = models.CharField(_("Prix"),max_length=100,default='',blank=True)
|
||||
lieux = models.CharField(_('Lieux'),max_length=100,default=' ',blank=True)
|
||||
date = models.DateField(_("Date"), max_length=100)
|
||||
instru = models.ForeignKey(
|
||||
"Instrument", on_delete=models.CASCADE, verbose_name=_("Instrument")
|
||||
)
|
||||
description = models.CharField(
|
||||
_("Description"), max_length=100, default=" ", blank=True
|
||||
)
|
||||
description_en = models.CharField(
|
||||
_("Description en anglais"), max_length=100, default=" ", blank=True
|
||||
)
|
||||
prix = models.CharField(_("Prix"), max_length=100, default="", blank=True)
|
||||
lieux = models.CharField(_("Lieux"), max_length=100, default=" ", blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.description
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Réparation')
|
||||
verbose_name_plural = _('Réparations')
|
||||
ordering = ('date',)
|
||||
verbose_name = _("Réparation")
|
||||
verbose_name_plural = _("Réparations")
|
||||
ordering = ("date",)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
{% extends "gestion/base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load autotranslate %}
|
||||
{% load halflength %}
|
||||
{% block titre %}{% trans "Instruments" %}{% endblock %}
|
||||
{% block content %}
|
||||
<div id="main">
|
||||
|
@ -19,9 +17,9 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/instruments.jpg' %}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div>
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div></div>
|
||||
{% endif %}
|
||||
</div></span>
|
||||
</span>
|
||||
{% if user.profile.is_chef %}
|
||||
<a href="{% url "instruments:ajouter_instru" %}" class="button alt big">{% trans "Ajouter un instrument" %}</a>
|
||||
{% endif %}
|
||||
|
@ -38,9 +36,9 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
{% for instrument in instrus_dispo %}
|
||||
<a href="{% url "instruments:fiche_instru" instrument.id %}">
|
||||
|
||||
<tr>
|
||||
<td> {{ instrument.type }} </td>
|
||||
<td> <a href="{% url "instruments:fiche_instru" instrument.id %}">{{ instrument.type }} </a></td>
|
||||
<td> {{ instrument.owner }} </td>
|
||||
<td> {{ instrument.etat }} </td>
|
||||
<td>
|
||||
|
@ -76,7 +74,7 @@
|
|||
{% for instrument in instrus_prete %}
|
||||
<tr>
|
||||
|
||||
<td> {{ instrument.type }} </td>
|
||||
<td> <a href="{% url "instruments:fiche_instru" instrument.id %}">{{ instrument.type }} </a> </td>
|
||||
<td> {{ instrument.owner }} </td>
|
||||
<td> {{ instrument.user }} </td>
|
||||
<td> {{ instrument.etat}} </td>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<div id="main">
|
||||
<section class="wrapper style1">
|
||||
<div class="inner">
|
||||
<h1>{% blocktrans with type=instru.type etat=instru.etat%} {{type}} en {{etat}} {% endblocktrans%}</h1>
|
||||
<h3>{% blocktrans with type=instru.type etat=instru.etat statut=instru.statut%} {{type}} en {{etat}} : {{statut}} {% endblocktrans%}</h3>
|
||||
<div class="row">
|
||||
|
||||
<div class="7u 12u$(small)">
|
||||
|
@ -22,11 +22,11 @@
|
|||
{% trans "Modele : "%} {{instru.model}} <br>
|
||||
{% trans "Numéro de série : "%} {{instru.serial}} <br>
|
||||
{% trans "Prix : "%} {{instru.prix}} <br>
|
||||
{% blocktrans with annee=instru.annee %} Acheté.e en {{annee}} {% endblocktrans%}
|
||||
{% blocktrans with annee=instru.annee %} Acheté·e en {{annee}} {% endblocktrans%}
|
||||
</p>
|
||||
{% if infos or infos_en %}
|
||||
|
||||
<h3>{% trans "Infos utiles :" %}</h3>
|
||||
<h1>{% trans "Infos utiles :" %}</h1>
|
||||
|
||||
<div class="box">{% autotranslate current_language infos infos_en %}</div>
|
||||
|
||||
|
@ -95,16 +95,6 @@
|
|||
{{ form.as_p }}
|
||||
<input type="submit" value="Enregister" />
|
||||
</form>
|
||||
{% else %}
|
||||
{% if instru.infos %}
|
||||
<div>
|
||||
<h4>Infos utiles</h4>
|
||||
<p>{{ infos }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from django.template.defaultfilters import urlencode
|
|||
from django.test import Client, TestCase
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
from ..models import Category, Partition, PartitionSet
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -11,12 +12,7 @@ User = get_user_model()
|
|||
|
||||
def new_user(username, ernesto=False, chef=False):
|
||||
u = User.objects.create_user(username=username)
|
||||
ErnestoUser.objects.create(
|
||||
user=u,
|
||||
slug=username,
|
||||
is_chef=chef,
|
||||
is_ernesto=ernesto
|
||||
)
|
||||
ErnestoUser.objects.create(user=u, slug=username, is_chef=chef, is_ernesto=ernesto)
|
||||
return u
|
||||
|
||||
|
||||
|
@ -32,16 +28,10 @@ class TestViews(TestCase):
|
|||
ernesto = new_user("ernesto", ernesto=True)
|
||||
ernesto_c = Client()
|
||||
ernesto_c.force_login(ernesto)
|
||||
self.client_matrix = [
|
||||
(chef, chef_c),
|
||||
(ernesto, ernesto_c),
|
||||
(None, Client())
|
||||
]
|
||||
self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())]
|
||||
# A Partition set with 1 partition
|
||||
self.pset = PartitionSet.objects.create(
|
||||
category=Category.objects.first(),
|
||||
nom="My PSet",
|
||||
auteur="PSet author"
|
||||
category=Category.objects.first(), nom="My PSet", auteur="PSet author"
|
||||
)
|
||||
file = File(open("partitions/tests/test_file.txt"), "test file")
|
||||
Partition.objects.create(nom="part1", part=file, morceau=self.pset)
|
||||
|
@ -90,9 +80,7 @@ class TestViews(TestCase):
|
|||
def test_download(self):
|
||||
"""Only ernesto members can download partitions"""
|
||||
part = self.pset.partition_set.first()
|
||||
url = "/partitions/{}/{}/{}".format(
|
||||
self.pset.nom, self.pset.auteur, part.id
|
||||
)
|
||||
url = "/partitions/{}/{}/{}".format(self.pset.nom, self.pset.auteur, part.id)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_new(self):
|
||||
|
|
|
@ -2,13 +2,15 @@ from django.urls import path
|
|||
|
||||
from . import views
|
||||
|
||||
app_name = 'instruments'
|
||||
app_name = "instruments"
|
||||
urlpatterns = [
|
||||
path('', views.liste, name='liste'),
|
||||
path("delete/<int:pk>", views.InstruDelete.as_view(), name="delete_instru"),
|
||||
path("delete_reparation/<int:pk>", views.delete_rep, name="delete_rep"),
|
||||
path("new", views.InstruCreate.as_view(), name="ajouter_instru"),
|
||||
path("new_rep/<int:pk>", views.create_rep, name="ajouter_rep"),
|
||||
path("update_rep/<int:pk>", views.RepUpdate.as_view(), name="update_rep"),
|
||||
path("fiche/<int:pk>",views.fiche_instru,name="fiche_instru"),
|
||||
path("", views.ListeInstru.as_view(), name="liste"),
|
||||
path("delete/<int:pk>", views.DeleteInstru.as_view(),
|
||||
name="delete_instru"),
|
||||
path("delete_reparation/<int:pk>", views.DeleteRep.as_view(),
|
||||
name="delete_rep"),
|
||||
path("new", views.CreateInstru.as_view(), name="ajouter_instru"),
|
||||
path("new_rep/<int:pk>", views.CreateRep.as_view(), name="ajouter_rep"),
|
||||
path("update_rep/<int:pk>", views.UpdateRep.as_view(), name="update_rep"),
|
||||
path("fiche/<int:pk>", views.FicheInstru.as_view(), name="fiche_instru"),
|
||||
]
|
||||
|
|
|
@ -1,104 +1,125 @@
|
|||
from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse
|
||||
from instruments.models import Instrument,Reparation
|
||||
from gestion.models import Photo
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.forms.models import modelform_factory
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.core.files import File
|
||||
from django.utils.encoding import smart_str
|
||||
from django.http import Http404
|
||||
from instruments.decorators import chef_required
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
import os
|
||||
import zipfile
|
||||
import io
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.http import HttpResponseRedirect
|
||||
@login_required
|
||||
def liste(request):
|
||||
photo = Photo.objects.filter(cat='instru').order_by('?').first()
|
||||
instrus_dispo = Instrument.objects.all().order_by('type').filter(statut='Disponible')
|
||||
instrus_prete = Instrument.objects.all().order_by('type').filter(statut='Prêté')
|
||||
return render(request, 'instruments/instru_liste.html', {"instrus_dispo":instrus_dispo,"instrus_prete":instrus_prete,"photo":photo})
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.views.generic import CreateView, DeleteView, UpdateView
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from gestion.models import Photo
|
||||
from instruments.forms import ChefEditInstrumentForm, ChefReparationForm
|
||||
from instruments.models import Instrument, Reparation
|
||||
|
||||
class InstruCreate(ChefRequiredMixin, CreateView):
|
||||
|
||||
class ListeInstru(LoginRequiredMixin, TemplateView):
|
||||
template_name = "instruments/instru_liste.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['photo'] = Photo.objects.filter(
|
||||
cat="instru").order_by("?").first()
|
||||
context['instrus_dispo'] = Instrument.objects.all().order_by(
|
||||
"type").filter(statut="Disponible")
|
||||
context['instrus_prete'] = Instrument.objects.all().order_by(
|
||||
"type").filter(statut="Prêté")
|
||||
return context
|
||||
|
||||
|
||||
class CreateInstru(ChefRequiredMixin, CreateView):
|
||||
model = Instrument
|
||||
fields = ["owner",'etat','type','marque','model','serial','annee','prix']
|
||||
fields = ["owner", "etat", "type", "marque",
|
||||
"model", "serial", "annee", "prix"]
|
||||
template_name = "instruments/create_instru.html"
|
||||
success_url = reverse_lazy("instruments:liste")
|
||||
|
||||
|
||||
@chef_required
|
||||
def create_rep(request, pk):
|
||||
ChefEditForm = modelform_factory(Reparation,
|
||||
fields=("date","description","description_en","prix",'lieux'))
|
||||
if request.method == "POST":
|
||||
form = ChefEditForm(request.POST)
|
||||
class CreateRep(ChefRequiredMixin, TemplateView):
|
||||
form_class = ChefReparationForm
|
||||
template_name = "instruments/create_rep.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["form"] = self.form_class()
|
||||
context["pk"] = self.kwargs['pk']
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
if form.is_valid():
|
||||
rep = Reparation()
|
||||
rep.date = form.cleaned_data['date']
|
||||
rep.description = form.cleaned_data['description']
|
||||
rep.description_en = form.cleaned_data['description_en']
|
||||
rep.prix = form.cleaned_data['prix']
|
||||
rep.lieux = form.cleaned_data['lieux']
|
||||
rep.id_instru = get_object_or_404(Instrument, id=pk)
|
||||
rep.date = form.cleaned_data["date"]
|
||||
rep.description = form.cleaned_data["description"]
|
||||
rep.description_en = form.cleaned_data["description_en"]
|
||||
rep.prix = form.cleaned_data["prix"]
|
||||
rep.lieux = form.cleaned_data["lieux"]
|
||||
rep.instru = get_object_or_404(Instrument, id=self.kwargs['pk'])
|
||||
rep.save()
|
||||
return redirect( 'instruments:fiche_instru', pk=pk)
|
||||
|
||||
else:
|
||||
form = ChefEditForm(request.POST)
|
||||
return render(request, 'instruments/create_rep.html', locals())
|
||||
return redirect("instruments:fiche_instru", pk=self.kwargs['pk'])
|
||||
else:
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
|
||||
@chef_required
|
||||
def delete_rep(request,pk):
|
||||
rep = get_object_or_404(Reparation, id=pk)
|
||||
|
||||
id_instru = rep.instru.id
|
||||
|
||||
rep.delete()
|
||||
suppression = _("Réparation supprimée")
|
||||
|
||||
|
||||
return redirect('instruments:fiche_instru',pk=id_instru)
|
||||
|
||||
@login_required
|
||||
def fiche_instru(request, pk):
|
||||
instru = get_object_or_404(Instrument, id=pk)
|
||||
reparations= Reparation.objects.filter(instru = pk).order_by('-date')
|
||||
ChefEditForm = modelform_factory(Instrument,
|
||||
fields=("statut","user","infos","type","owner","marque","model","serial","annee","prix","infos_en"))
|
||||
if request.method == "POST" and request.user.profile.is_chef:
|
||||
form = ChefEditForm(request.POST, instance=instru)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
form = ChefEditForm(instance=instru)
|
||||
infos = mark_safe(instru.infos)
|
||||
infos_en = mark_safe(instru.infos_en)
|
||||
return render(request, 'instruments/update_instru.html', locals())
|
||||
|
||||
|
||||
class RepUpdate(ChefRequiredMixin, UpdateView):
|
||||
class DeleteRep(ChefRequiredMixin, TemplateView):
|
||||
model = Reparation
|
||||
fields = ["date","description","description_en","prix",'lieux']
|
||||
template_name = "instruments/delete_instru.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
rep = get_object_or_404(self.model, id=self.kwargs['pk'])
|
||||
id_instru = rep.instru.id
|
||||
rep.delete()
|
||||
return redirect("instruments:fiche_instru", pk=id_instru)
|
||||
|
||||
|
||||
class FicheInstru(LoginRequiredMixin, TemplateView):
|
||||
|
||||
template_name = "instruments/update_instru.html"
|
||||
model = Instrument
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
instru = get_object_or_404(self.model, id=self.kwargs['pk'])
|
||||
reparations = Reparation.objects.filter(
|
||||
instru=self.kwargs['pk']).order_by("-date")
|
||||
|
||||
form = ChefEditInstrumentForm(instance=instru)
|
||||
infos = mark_safe(instru.infos)
|
||||
infos_en = mark_safe(instru.infos_en)
|
||||
|
||||
context["reparations"] = reparations
|
||||
context["instru"] = instru
|
||||
context["form"] = form
|
||||
context["infos"] = infos
|
||||
context["infos_en"] = infos_en
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
instru = get_object_or_404(self.model, id=self.kwargs['pk'])
|
||||
form = ChefEditInstrumentForm(request.POST, instance=instru)
|
||||
if request.user.profile.is_chef:
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class UpdateRep(ChefRequiredMixin, UpdateView):
|
||||
model = Reparation
|
||||
fields = ["date", "description", "description_en", "prix", "lieux"]
|
||||
template_name = "instruments/update_rep.html"
|
||||
|
||||
def get_success_url(self):
|
||||
# if you are passing 'pk' from 'urls' to 'DeleteView' for company
|
||||
# capture that 'pk' as companyid and pass it to 'reverse_lazy()' function
|
||||
id_instru=get_object_or_404(Reparation, id=self.kwargs['pk']).instru.id
|
||||
return reverse_lazy('instruments:fiche_instru', kwargs={'pk': id_instru})
|
||||
id_instru = get_object_or_404(Reparation,
|
||||
id=self.kwargs["pk"]).instru.id
|
||||
return reverse_lazy("instruments:fiche_instru",
|
||||
kwargs={"pk": id_instru})
|
||||
|
||||
class InstruDelete(ChefRequiredMixin, DeleteView):
|
||||
|
||||
class DeleteInstru(ChefRequiredMixin, DeleteView):
|
||||
model = Instrument
|
||||
template_name = "instruments/delete_instru.html"
|
||||
success_url = reverse_lazy("instruments:liste")
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load diff
|
@ -3,10 +3,7 @@ import os
|
|||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault(
|
||||
"DJANGO_SETTINGS_MODULE",
|
||||
"Ernestophone.settings.local"
|
||||
)
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Ernestophone.settings.local")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class PadsConfig(AppConfig):
|
||||
name = 'pads'
|
||||
name = "pads"
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
from django import forms
|
||||
|
||||
from pads.models import Pad
|
||||
|
||||
|
||||
class PadForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Pad
|
||||
fields = ('nom', 'url',)
|
||||
fields = (
|
||||
"nom",
|
||||
"url",
|
||||
)
|
||||
|
|
|
@ -6,20 +6,27 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Pad',
|
||||
name="Pad",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('url', models.URLField()),
|
||||
('date', models.DateField(verbose_name='Créé le')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("url", models.URLField()),
|
||||
("date", models.DateField(verbose_name="Créé le")),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Pad',
|
||||
"verbose_name": "Pad",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
@ -6,13 +6,13 @@ from django.db import migrations, models
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pads', '0001_initial'),
|
||||
("pads", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='pad',
|
||||
name='date',
|
||||
field=models.DateField(verbose_name='Cree le'),
|
||||
model_name="pad",
|
||||
name="date",
|
||||
field=models.DateField(verbose_name="Cree le"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -11,4 +11,6 @@ class Pad(models.Model):
|
|||
|
||||
class Meta:
|
||||
verbose_name = "Pad"
|
||||
|
||||
|
||||
# Create your models here.
|
||||
|
|
|
@ -2,7 +2,6 @@ from django.urls import path
|
|||
|
||||
from pads import views
|
||||
|
||||
|
||||
app_name = "pads"
|
||||
urlpatterns = [
|
||||
path("", views.PadList.as_view(), name="list"),
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.http import HttpResponseRedirect
|
|||
from django.urls import reverse_lazy
|
||||
from django.utils import timezone
|
||||
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
|
||||
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
from pads.models import Pad
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
|
||||
from .models import Category,PartitionSet
|
||||
from .models import Category, PartitionSet
|
||||
|
||||
admin.site.register(Category)
|
||||
admin.site.register(PartitionSet)
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class PartitionsConfig(AppConfig):
|
||||
name = 'partitions'
|
||||
name = "partitions"
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
from django.contrib.auth.decorators import user_passes_test
|
||||
|
||||
|
||||
def is_chef(user):
|
||||
try:
|
||||
profile = user.profile
|
||||
return profile.is_chef
|
||||
except:
|
||||
return False
|
||||
|
||||
chef_required = user_passes_test(lambda u: is_chef(u))
|
|
@ -1,5 +1,7 @@
|
|||
from django import forms
|
||||
|
||||
from .models import PartitionSet
|
||||
|
||||
|
||||
class UploadFileForm(forms.Form):
|
||||
title = forms.CharField(max_length=50)
|
||||
|
@ -9,3 +11,9 @@ class UploadFileForm(forms.Form):
|
|||
class UploadMorceauForm(forms.Form):
|
||||
titre = forms.CharField(max_length=100)
|
||||
auteur = forms.CharField(max_length=100)
|
||||
|
||||
|
||||
class ChefEditMorceauForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = PartitionSet
|
||||
fields = ("category", "download_unlogged", "infos", "url", "infos_en")
|
||||
|
|
|
@ -6,31 +6,66 @@ from django.db import migrations, models
|
|||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Partition',
|
||||
name="Partition",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('part', models.FileField(upload_to='partitions/')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("part", models.FileField(upload_to="partitions/")),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PartitionSet',
|
||||
name="PartitionSet",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, verbose_name='ID', serialize=False)),
|
||||
('nom', models.CharField(max_length=100)),
|
||||
('auteur', models.CharField(max_length=100)),
|
||||
('category', models.CharField(max_length=8, choices=[('active', 'Actif'), ('incoming', 'À venir'), ('old', 'Archive'), ('optional', 'Optionnel')], default='incoming', verbose_name='Types de partitions')),
|
||||
('infos', models.TextField(blank=True, verbose_name='Infos utiles', null=True)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID",
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("nom", models.CharField(max_length=100)),
|
||||
("auteur", models.CharField(max_length=100)),
|
||||
(
|
||||
"category",
|
||||
models.CharField(
|
||||
max_length=8,
|
||||
choices=[
|
||||
("active", "Actif"),
|
||||
("incoming", "À venir"),
|
||||
("old", "Archive"),
|
||||
("optional", "Optionnel"),
|
||||
],
|
||||
default="incoming",
|
||||
verbose_name="Types de partitions",
|
||||
),
|
||||
),
|
||||
(
|
||||
"infos",
|
||||
models.TextField(
|
||||
blank=True, verbose_name="Infos utiles", null=True
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partition',
|
||||
name='morceau',
|
||||
field=models.ForeignKey(to='partitions.PartitionSet', on_delete=models.CASCADE),
|
||||
model_name="partition",
|
||||
name="morceau",
|
||||
field=models.ForeignKey(
|
||||
to="partitions.PartitionSet", on_delete=models.CASCADE
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def create_categories(apps, schema_editor):
|
||||
# Insert the previously hardcoded categories in the database
|
||||
Category = apps.get_model("partitions", "Category")
|
||||
Category.objects.bulk_create([
|
||||
Category(name="Partitions actives", order=1),
|
||||
Category(name="Partitions optionnelles", order=2),
|
||||
Category(name="Partitions à venir", order=3),
|
||||
Category(name="Archives", order=4)
|
||||
])
|
||||
Category.objects.bulk_create(
|
||||
[
|
||||
Category(name="Partitions actives", order=1),
|
||||
Category(name="Partitions optionnelles", order=2),
|
||||
Category(name="Partitions à venir", order=3),
|
||||
Category(name="Archives", order=4),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def set_new_categories(apps, schema_editor):
|
||||
|
@ -24,7 +26,7 @@ def set_new_categories(apps, schema_editor):
|
|||
"active": assoc_list[0],
|
||||
"incoming": assoc_list[2],
|
||||
"old": assoc_list[3],
|
||||
"optional": assoc_list[1]
|
||||
"optional": assoc_list[1],
|
||||
}
|
||||
for par_set in PartitionSet.objects.all():
|
||||
par_set.category = mapping[par_set.category_old]
|
||||
|
@ -39,7 +41,7 @@ def reset_old_categories(apps, schema_editor):
|
|||
assoc_list[0][1]: "active",
|
||||
assoc_list[2][1]: "incoming",
|
||||
assoc_list[3][1]: "old",
|
||||
assoc_list[1][1]: "optional"
|
||||
assoc_list[1][1]: "optional",
|
||||
}
|
||||
for par_set in PartitionSet.objects.all():
|
||||
par_set.category_old = mapping[par_set.category]
|
||||
|
@ -49,29 +51,39 @@ def reset_old_categories(apps, schema_editor):
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0001_initial'),
|
||||
("partitions", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Category',
|
||||
name="Category",
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
|
||||
('name', models.CharField(max_length=127)),
|
||||
('order', models.IntegerField(verbose_name='order')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
verbose_name="ID",
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
auto_created=True,
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=127)),
|
||||
("order", models.IntegerField(verbose_name="order")),
|
||||
],
|
||||
options={'verbose_name': 'catégorie', 'verbose_name_plural': 'catégories'},
|
||||
options={"verbose_name": "catégorie", "verbose_name_plural": "catégories"},
|
||||
),
|
||||
migrations.RunPython(create_categories, migrations.RunPython.noop),
|
||||
migrations.RenameField(model_name="partitionset", old_name="category", new_name="category_old"),
|
||||
migrations.RenameField(
|
||||
model_name="partitionset", old_name="category", new_name="category_old"
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='category',
|
||||
model_name="partitionset",
|
||||
name="category",
|
||||
field=models.ForeignKey(
|
||||
verbose_name='Type de partition',
|
||||
to='partitions.Category',
|
||||
verbose_name="Type de partition",
|
||||
to="partitions.Category",
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
default=1 # Dummy, will be set by the RunPython operation
|
||||
default=1, # Dummy, will be set by the RunPython operation
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
|
|
|
@ -1,47 +1,78 @@
|
|||
# Generated by Django 2.2.14 on 2020-07-16 17:49
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.expressions
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0002_category'),
|
||||
("partitions", "0002_category"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='category',
|
||||
options={'ordering': ('order',), 'verbose_name': 'Categorie', 'verbose_name_plural': 'Categories'},
|
||||
name="category",
|
||||
options={
|
||||
"ordering": ("order",),
|
||||
"verbose_name": "Categorie",
|
||||
"verbose_name_plural": "Categories",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partition',
|
||||
options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partition",
|
||||
options={
|
||||
"ordering": (
|
||||
django.db.models.expressions.CombinedExpression(
|
||||
django.db.models.expressions.Value("-"),
|
||||
"+",
|
||||
django.db.models.functions.text.Lower("nom"),
|
||||
),
|
||||
),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partitionset',
|
||||
options={'ordering': (django.db.models.expressions.CombinedExpression(django.db.models.expressions.Value('-'), '+', django.db.models.functions.text.Lower('nom')),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partitionset",
|
||||
options={
|
||||
"ordering": (
|
||||
django.db.models.expressions.CombinedExpression(
|
||||
django.db.models.expressions.Value("-"),
|
||||
"+",
|
||||
django.db.models.functions.text.Lower("nom"),
|
||||
),
|
||||
),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='category',
|
||||
name='nom_en',
|
||||
model_name="category",
|
||||
name="nom_en",
|
||||
field=models.CharField(blank=True, max_length=100, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='infos_en',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='Infos utiles en anglais'),
|
||||
model_name="partitionset",
|
||||
name="infos_en",
|
||||
field=models.TextField(
|
||||
blank=True, null=True, verbose_name="Infos utiles en anglais"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='url',
|
||||
field=models.URLField(blank=True, help_text='Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse', null=True, verbose_name="Url d'une video youtube"),
|
||||
model_name="partitionset",
|
||||
name="url",
|
||||
field=models.URLField(
|
||||
blank=True,
|
||||
help_text="Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse",
|
||||
null=True,
|
||||
verbose_name="Url d'une video youtube",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='category',
|
||||
name='order',
|
||||
field=models.IntegerField(verbose_name='ordre'),
|
||||
model_name="category",
|
||||
name="order",
|
||||
field=models.IntegerField(verbose_name="ordre"),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,37 +1,52 @@
|
|||
# Generated by Django 2.2.17 on 2021-03-31 13:50
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.functions.text
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('partitions', '0003_auto_20200716_1749'),
|
||||
("partitions", "0003_auto_20200716_1749"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='partition',
|
||||
options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partition",
|
||||
options={
|
||||
"ordering": (django.db.models.functions.text.Lower("nom"),),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='partitionset',
|
||||
options={'ordering': (django.db.models.functions.text.Lower('nom'),), 'verbose_name': 'Morceau', 'verbose_name_plural': 'Morceaux'},
|
||||
name="partitionset",
|
||||
options={
|
||||
"ordering": (django.db.models.functions.text.Lower("nom"),),
|
||||
"verbose_name": "Morceau",
|
||||
"verbose_name_plural": "Morceaux",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='partitionset',
|
||||
name='download_unlogged',
|
||||
field=models.CharField(choices=[('n', 'Non'), ('o', 'Oui')], default='n', max_length=1, verbose_name='Téléchargeable non connecté ?'),
|
||||
model_name="partitionset",
|
||||
name="download_unlogged",
|
||||
field=models.CharField(
|
||||
choices=[("n", "Non"), ("o", "Oui")],
|
||||
default="n",
|
||||
max_length=1,
|
||||
verbose_name="Téléchargeable non connecté ?",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='partitionset',
|
||||
name='infos',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Infos utiles'),
|
||||
model_name="partitionset",
|
||||
name="infos",
|
||||
field=models.TextField(blank=True, default="", verbose_name="Infos utiles"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='partitionset',
|
||||
name='infos_en',
|
||||
field=models.TextField(blank=True, default='', verbose_name='Infos utiles en anglais'),
|
||||
model_name="partitionset",
|
||||
name="infos_en",
|
||||
field=models.TextField(
|
||||
blank=True, default="", verbose_name="Infos utiles en anglais"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -2,29 +2,28 @@ import os
|
|||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from colorful.fields import RGBColorField
|
||||
from django.db.models.functions import Lower
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
name = models.CharField(max_length=127)
|
||||
order = models.IntegerField(verbose_name=_("ordre"))
|
||||
nom_en = models.CharField(max_length=100,null=True,blank=True)
|
||||
nom_en = models.CharField(max_length=100, null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Categorie")
|
||||
verbose_name_plural = _("Categories")
|
||||
ordering = ('order',)
|
||||
ordering = ("order",)
|
||||
|
||||
|
||||
class Partition(models.Model):
|
||||
nom = models.CharField(max_length=100)
|
||||
part = models.FileField(upload_to="partitions/")
|
||||
morceau = models.ForeignKey('PartitionSet', on_delete=models.CASCADE)
|
||||
morceau = models.ForeignKey("PartitionSet", on_delete=models.CASCADE)
|
||||
|
||||
def __str__(self):
|
||||
return self.nom
|
||||
|
@ -34,26 +33,40 @@ class Partition(models.Model):
|
|||
super(Partition, self).delete(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Morceau')
|
||||
verbose_name_plural = _('Morceaux')
|
||||
ordering = (Lower('nom'),)
|
||||
verbose_name = _("Morceau")
|
||||
verbose_name_plural = _("Morceaux")
|
||||
ordering = (Lower("nom"),)
|
||||
|
||||
|
||||
class PartitionSet(models.Model):
|
||||
nom = models.CharField(max_length=100)
|
||||
auteur = models.CharField(max_length=100)
|
||||
category = models.ForeignKey(
|
||||
Category,
|
||||
on_delete=models.PROTECT,
|
||||
verbose_name=_("Type de partition")
|
||||
Category, on_delete=models.PROTECT, verbose_name=_("Type de partition")
|
||||
)
|
||||
download_unlogged = models.CharField(_("Téléchargeable non connecté ?"),default='n',choices = [('n',_('Non')),('o',_('Oui'))],max_length=1)
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True,default="")
|
||||
infos_en = models.TextField("Infos utiles en anglais", null=False, blank=True,default="")
|
||||
url = models.URLField(_("Url d'une video youtube"),null=True,blank=True, help_text= _("Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse"))
|
||||
download_unlogged = models.CharField(
|
||||
_("Téléchargeable non connecté ?"),
|
||||
default="n",
|
||||
choices=[("n", _("Non")), ("o", _("Oui"))],
|
||||
max_length=1,
|
||||
)
|
||||
infos = models.TextField(_("Infos utiles"), null=False, blank=True, default="")
|
||||
infos_en = models.TextField(
|
||||
"Infos utiles en anglais", null=False, blank=True, default=""
|
||||
)
|
||||
url = models.URLField(
|
||||
_("Url d'une video youtube"),
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text=_(
|
||||
"Dans Youtube cliquer sur partager puis importer pour récuperer la bonne adresse"
|
||||
),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return("%s - %s [%s]" % (self.nom, self.auteur, self.category))
|
||||
return "%s - %s [%s]" % (self.nom, self.auteur, self.category)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Morceau')
|
||||
verbose_name_plural = _('Morceaux')
|
||||
ordering = (Lower('nom'),)
|
||||
verbose_name = _("Morceau")
|
||||
verbose_name_plural = _("Morceaux")
|
||||
ordering = (Lower("nom"),)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="inner">
|
||||
|
||||
<h4>{% trans "Confirmation de suppression" %}</h4>
|
||||
<p>{% trans "Voulez-vous vraiment supprimer cette partition ?" %}"</p>
|
||||
<p>{% trans "Voulez-vous vraiment supprimer cette partition ?" %}</p>
|
||||
<p><a href="{% url "partitions:delete" nom auteur id %}" class="button " >{% trans "Oui" %}</a></p>
|
||||
<p><a href="{% url "partitions:listepart" nom auteur %}" class="button alt" >{% trans "Retour à la liste des partitions" %}</a></p>
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
<div class="box">{% autotranslate current_language infos infos_en %}</div>
|
||||
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<img src="{% static 'images/all_repertoire.jpg' %}" alt="" /> <div style="position:absolute;z-index:1;right:0;bottom:0">
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div>
|
||||
<div class="icon fa-copyright" style="color:#000000"> Lucas Gierzack</div></div>
|
||||
{% endif %}
|
||||
</div></span>
|
||||
</span>
|
||||
{% if user.profile.is_chef %}
|
||||
<a href="{% url "partitions:ajouter_morceau" %}" class="button alt big">{% trans "Ajouter un morceau" %}</a>   <a href="{% url "partitions:download_musecores" %}" class="button alt big">{% trans "Télécharger tous les musecores actifs" %}</a>
|
||||
{% elif user.is_authenticated %}
|
||||
|
|
|
@ -4,6 +4,7 @@ from django.template.defaultfilters import urlencode
|
|||
from django.test import Client, TestCase
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
|
||||
from ..models import Category, Partition, PartitionSet
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -11,12 +12,7 @@ User = get_user_model()
|
|||
|
||||
def new_user(username, ernesto=False, chef=False):
|
||||
u = User.objects.create_user(username=username)
|
||||
ErnestoUser.objects.create(
|
||||
user=u,
|
||||
slug=username,
|
||||
is_chef=chef,
|
||||
is_ernesto=ernesto
|
||||
)
|
||||
ErnestoUser.objects.create(user=u, slug=username, is_chef=chef, is_ernesto=ernesto)
|
||||
return u
|
||||
|
||||
|
||||
|
@ -32,16 +28,10 @@ class TestViews(TestCase):
|
|||
ernesto = new_user("ernesto", ernesto=True)
|
||||
ernesto_c = Client()
|
||||
ernesto_c.force_login(ernesto)
|
||||
self.client_matrix = [
|
||||
(chef, chef_c),
|
||||
(ernesto, ernesto_c),
|
||||
(None, Client())
|
||||
]
|
||||
self.client_matrix = [(chef, chef_c), (ernesto, ernesto_c), (None, Client())]
|
||||
# A Partition set with 1 partition
|
||||
self.pset = PartitionSet.objects.create(
|
||||
category=Category.objects.first(),
|
||||
nom="My PSet",
|
||||
auteur="PSet author"
|
||||
category=Category.objects.first(), nom="My PSet", auteur="PSet author"
|
||||
)
|
||||
file = File(open("partitions/tests/test_file.txt"), "test file")
|
||||
Partition.objects.create(nom="part1", part=file, morceau=self.pset)
|
||||
|
@ -90,9 +80,7 @@ class TestViews(TestCase):
|
|||
def test_download(self):
|
||||
"""Only ernesto members can download partitions"""
|
||||
part = self.pset.partition_set.first()
|
||||
url = "/partitions/{}/{}/{}".format(
|
||||
self.pset.nom, self.pset.auteur, part.id
|
||||
)
|
||||
url = "/partitions/{}/{}/{}".format(self.pset.nom, self.pset.auteur, part.id)
|
||||
self._get_restricted_page(url)
|
||||
|
||||
def test_new(self):
|
||||
|
|
|
@ -2,17 +2,26 @@ from django.urls import path
|
|||
|
||||
from . import views
|
||||
|
||||
app_name = 'partitions'
|
||||
app_name = "partitions"
|
||||
urlpatterns = [
|
||||
path('', views.liste, name='liste'),
|
||||
path('download', views.download_musecores, name='download_musecores'),
|
||||
path("<str:nom>/<str:auteur>/upload", views.upload, name="upload"),
|
||||
path("<str:nom>/<str:auteur>", views.listepart, name="listepart"),
|
||||
path("<str:nom>/<str:auteur>/see/<int:partition_id>", views.see, name="see"),
|
||||
path("<str:nom>/<str:auteur>/<int:partition_id>", views.download, name="download"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/conf", views.conf_delete, name="conf_delete"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/delete", views.delete, name="delete"),
|
||||
path("<str:nom>/<str:auteur>/delete", views.delete_morc, name="delete_morc"),
|
||||
path("<str:nom>/<str:auteur>/conf", views.conf_delete_morc, name="conf_delete_morc"),
|
||||
path("new", views.ajouter_morceau, name="ajouter_morceau"),
|
||||
path("", views.Repertoire.as_view(), name="liste"),
|
||||
path("download", views.download_musecores, name="download_musecores"),
|
||||
path("<str:nom>/<str:auteur>/upload", views.Upload.as_view(),
|
||||
name="upload"),
|
||||
path("<str:nom>/<str:auteur>", views.Morceau.as_view(), name="listepart"),
|
||||
path("<str:nom>/<str:auteur>/see/<int:partition_id>", views.see,
|
||||
name="see"),
|
||||
path("<str:nom>/<str:auteur>/<int:partition_id>", views.download,
|
||||
name="download"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/conf", views.ConfDelete.as_view(),
|
||||
name="conf_delete"),
|
||||
path("<str:nom>/<str:auteur>/<int:id>/delete", views.DeletePart.as_view(),
|
||||
name="delete"),
|
||||
path("<str:nom>/<str:auteur>/delete", views.DeleteMorc.as_view(),
|
||||
name="delete_morc"),
|
||||
path(
|
||||
"<str:nom>/<str:auteur>/conf", views.ConfDeleteMorc.as_view(),
|
||||
name="conf_delete_morc"
|
||||
),
|
||||
path("new", views.CreateMorc.as_view(), name="ajouter_morceau"),
|
||||
]
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
from django.shortcuts import render, HttpResponse, get_object_or_404, redirect, reverse
|
||||
from partitions.models import Category, Partition, PartitionSet
|
||||
from gestion.models import Photo
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from partitions.forms import UploadFileForm, UploadMorceauForm
|
||||
from django.forms.models import modelform_factory
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.core.files import File
|
||||
from django.utils.encoding import smart_str
|
||||
from django.http import Http404
|
||||
from partitions.decorators import chef_required
|
||||
from django.conf import settings
|
||||
from django.db.models import Q
|
||||
import io
|
||||
import os
|
||||
import zipfile
|
||||
import io
|
||||
|
||||
from django.core.files import File
|
||||
from django.db.models import Q
|
||||
from django.http import Http404
|
||||
from django.shortcuts import HttpResponse, get_object_or_404, redirect, render
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from gestion.models import Photo
|
||||
from partitions.forms import UploadFileForm, UploadMorceauForm
|
||||
from partitions.models import Category, Partition, PartitionSet
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
from .forms import ChefEditMorceauForm
|
||||
from gestion.mixins import ChefRequiredMixin
|
||||
|
||||
|
||||
def download_musecores(request):
|
||||
|
||||
p = Partition.objects.filter(Q(part__contains = ".mscz") & Q(Q(morceau__category__name = "Partitions actives" )|Q(morceau__category__name = "Partitions optionnelles" )))
|
||||
|
||||
|
||||
p = Partition.objects.filter(
|
||||
Q(part__contains=".mscz")
|
||||
& Q(
|
||||
Q(morceau__category__name="Partitions actives")
|
||||
| Q(morceau__category__name="Partitions optionnelles")
|
||||
)
|
||||
)
|
||||
|
||||
zip_subdir = "Ernestophone_musescores"
|
||||
zip_filename = "%s.zip" % zip_subdir
|
||||
|
@ -32,14 +39,22 @@ def download_musecores(request):
|
|||
# The zip compressor
|
||||
zf = zipfile.ZipFile(s, "w")
|
||||
|
||||
for part in p :
|
||||
for part in p:
|
||||
fpath = part.part.path
|
||||
|
||||
typ=".mscz"
|
||||
typ = ".mscz"
|
||||
# Calculate path for file in zip
|
||||
fdir, fname = os.path.split(fpath)
|
||||
zip_path = os.path.join(zip_subdir, '%s_%s_%s.%s' % (
|
||||
slugify(part.morceau.nom), slugify(part.morceau.auteur), slugify(part.nom), typ))
|
||||
zip_path = os.path.join(
|
||||
zip_subdir,
|
||||
"%s_%s_%s.%s"
|
||||
% (
|
||||
slugify(part.morceau.nom),
|
||||
slugify(part.morceau.auteur),
|
||||
slugify(part.nom),
|
||||
typ,
|
||||
),
|
||||
)
|
||||
|
||||
# Add file, at correct path
|
||||
zf.write(fpath, zip_path)
|
||||
|
@ -49,70 +64,117 @@ def download_musecores(request):
|
|||
# Grab ZIP file from in-memory, make response with correct MIME-type
|
||||
resp = HttpResponse(s.getvalue())
|
||||
# ..and correct content-disposition
|
||||
resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
|
||||
resp["Content-Disposition"] = "attachment; filename=%s" % zip_filename
|
||||
|
||||
return resp
|
||||
|
||||
def liste(request):
|
||||
categories = Category.objects.prefetch_related("partitionset_set").order_by("order")
|
||||
photo = Photo.objects.filter(cat='part').order_by('?').first()
|
||||
return render(request, 'partitions/repertoire.html', {"categories": categories,"photo":photo})
|
||||
|
||||
@login_required
|
||||
def listepart(request, nom, auteur):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all().order_by('nom')
|
||||
ChefEditForm = modelform_factory(PartitionSet,
|
||||
fields=("category","download_unlogged", "infos","url","infos_en"))
|
||||
if request.method == "POST" and request.user.profile.is_chef:
|
||||
form = ChefEditForm(request.POST, instance=p)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
form = ChefEditForm(instance=p)
|
||||
infos = mark_safe(p.infos)
|
||||
infos_en = mark_safe(p.infos_en)
|
||||
return render(request, 'partitions/part.html', locals())
|
||||
class Repertoire(TemplateView):
|
||||
template_name = "partitions/repertoire.html"
|
||||
|
||||
@chef_required
|
||||
def upload(request, nom, auteur):
|
||||
if request.method == "POST":
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['categories'] = Category.objects.prefetch_related(
|
||||
"partitionset_set").order_by("order")
|
||||
context['photo'] = Photo.objects.filter(
|
||||
cat="part").order_by("?").first()
|
||||
return context
|
||||
|
||||
|
||||
class Morceau(LoginRequiredMixin, TemplateView):
|
||||
template_name = "partitions/part.html"
|
||||
form_class = ChefEditMorceauForm
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Morceau, self).get_context_data(**kwargs)
|
||||
p = get_object_or_404(PartitionSet, nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
part = p.partition_set.all().order_by("nom")
|
||||
form = self.form_class(instance=p)
|
||||
infos = mark_safe(p.infos)
|
||||
infos_en = mark_safe(p.infos_en)
|
||||
|
||||
context["p"] = p
|
||||
context["infos"] = infos
|
||||
context["infos_en"] = infos_en
|
||||
context["form"] = form
|
||||
context["part"] = part
|
||||
context["nom"] = self.kwargs['nom']
|
||||
context["auteur"] = self.kwargs['auteur']
|
||||
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
p = get_object_or_404(PartitionSet, nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
if request.user.profile.is_chef:
|
||||
form = self.form_class(request.POST, instance=p)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
context = self.get_context_data()
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class Upload(ChefRequiredMixin, TemplateView):
|
||||
form_class = UploadFileForm
|
||||
sauvegarde = False
|
||||
error = False
|
||||
template_name = "partitions/upload.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(Upload, self).get_context_data(**kwargs)
|
||||
form = self.form_class()
|
||||
|
||||
context["sauvegarde"] = self.sauvegarde
|
||||
context["nom"] = self.kwargs['nom']
|
||||
context["auteur"] = self.kwargs['auteur']
|
||||
context["form"] = form
|
||||
context["error"] = self.error
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = UploadFileForm(request.POST, request.FILES)
|
||||
if form.is_valid():
|
||||
partition = Partition()
|
||||
partition.part = form.cleaned_data['file']
|
||||
partition.nom = form.cleaned_data['title']
|
||||
if '/' in partition.nom:
|
||||
error = _("Le caractère / n'est pas autorisé dans le nom")
|
||||
form = UploadFileForm()
|
||||
return render(request, "partitions/upload.html", locals())
|
||||
mor = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
partition.part = form.cleaned_data["file"]
|
||||
partition.nom = form.cleaned_data["title"]
|
||||
if "/" in partition.nom:
|
||||
self.error = _("Le caractère / n'est pas autorisé dans le nom")
|
||||
context = self.get_context_data()
|
||||
return render(request, self.template_name, context)
|
||||
mor = get_object_or_404(PartitionSet, nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
partition.morceau = mor
|
||||
try:
|
||||
mor.partition_set.get(nom=partition.nom)
|
||||
error = _("Un morceau du même nom existe déjà")
|
||||
self.error = _("Un morceau du même nom existe déjà")
|
||||
except Partition.DoesNotExist:
|
||||
partition.save()
|
||||
sauvegarde = True
|
||||
else:
|
||||
form = UploadFileForm()
|
||||
return render(request, 'partitions/upload.html', locals())
|
||||
self.sauvegarde = True
|
||||
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
def see(request, nom, auteur, partition_id):
|
||||
partition = get_object_or_404(Partition, id=partition_id)
|
||||
_, extension = os.path.splitext(partition.part.path)
|
||||
download_unlogged = partition.morceau.download_unlogged
|
||||
if(download_unlogged == 'o' or request.user.is_authenticated):
|
||||
if download_unlogged == "o" or request.user.is_authenticated:
|
||||
if ".pdf" == extension:
|
||||
with open(partition.part.path, 'rb') as f:
|
||||
with open(partition.part.path, "rb") as f:
|
||||
myfile = File(f)
|
||||
response = HttpResponse(content=myfile.read())
|
||||
response["Content-Type"] = "application/pdf"
|
||||
response["Content-Disposition"] = "inline; filename=%s_%s_%s.pdf" % (
|
||||
slugify(nom), slugify(auteur), slugify(partition.nom))
|
||||
slugify(nom),
|
||||
slugify(auteur),
|
||||
slugify(partition.nom),
|
||||
)
|
||||
return response
|
||||
elif ".mp3" == extension:
|
||||
with open(partition.part.path, 'rb') as f:
|
||||
with open(partition.part.path, "rb") as f:
|
||||
myfile = File(f)
|
||||
response = HttpResponse()
|
||||
response.write(myfile.read())
|
||||
|
@ -122,38 +184,56 @@ def see(request, nom, auteur, partition_id):
|
|||
else:
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all()
|
||||
return render(request, 'partitions/part.html', locals())
|
||||
else :
|
||||
return redirect('login')
|
||||
return render(
|
||||
request,
|
||||
"partitions/part.html",
|
||||
{"p": p, "part": part, "nom": nom, "auteur": auteur},
|
||||
)
|
||||
else:
|
||||
return redirect("login")
|
||||
|
||||
@chef_required
|
||||
def delete(request, nom, auteur, id):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
try:
|
||||
part = p.partition_set.get(id=id)
|
||||
except Partition.DoesNotExist:
|
||||
raise Http404
|
||||
part.delete()
|
||||
suppression = _("Partition supprimée")
|
||||
p.refresh_from_db()
|
||||
part = p.partition_set.all()
|
||||
return redirect('partitions:listepart',nom=nom,auteur=auteur)
|
||||
|
||||
@chef_required
|
||||
def ajouter_morceau(request):
|
||||
if request.method == "POST":
|
||||
form = UploadMorceauForm(request.POST)
|
||||
class DeletePart(ChefRequiredMixin, TemplateView):
|
||||
model = PartitionSet
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
p = get_object_or_404(self.model, nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
try:
|
||||
part = p.partition_set.get(id=self.kwargs['id'])
|
||||
except Partition.DoesNotExist:
|
||||
raise Http404
|
||||
part.delete()
|
||||
return redirect("partitions:listepart", nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
|
||||
|
||||
class CreateMorc(ChefRequiredMixin, TemplateView):
|
||||
form_class = UploadMorceauForm
|
||||
template_name = "partitions/new.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CreateMorc, self).get_context_data(**kwargs)
|
||||
context['form'] = self.form_class()
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST)
|
||||
sauvegarde = False
|
||||
error = False
|
||||
if form.is_valid():
|
||||
partitionset = PartitionSet()
|
||||
partitionset.nom = form.cleaned_data['titre']
|
||||
partitionset.auteur = form.cleaned_data['auteur']
|
||||
if '/' in partitionset.auteur or '/' in partitionset.nom:
|
||||
partitionset.nom = form.cleaned_data["titre"]
|
||||
partitionset.auteur = form.cleaned_data["auteur"]
|
||||
if "/" in partitionset.auteur or "/" in partitionset.nom:
|
||||
error = _("Le caractère / n'est pas autorisé")
|
||||
form = UploadMorceauForm()
|
||||
return render(request, 'partitions/new.html', locals())
|
||||
context = self.get_context_data()
|
||||
context['error'] = error
|
||||
return render(request, self.template_name, context)
|
||||
try:
|
||||
PartitionSet.objects.get(nom=partitionset.nom,
|
||||
auteur=partitionset.auteur)
|
||||
PartitionSet.objects.get(
|
||||
nom=partitionset.nom, auteur=partitionset.auteur
|
||||
)
|
||||
error = _("Un morceau du même nom existe déjà")
|
||||
except PartitionSet.DoesNotExist:
|
||||
# XXX. Hideous
|
||||
|
@ -165,50 +245,64 @@ def ajouter_morceau(request):
|
|||
partitionset.category = cat
|
||||
partitionset.save()
|
||||
sauvegarde = True
|
||||
return redirect('partitions:liste')
|
||||
else:
|
||||
form = UploadMorceauForm()
|
||||
return render(request, 'partitions/new.html', locals())
|
||||
return redirect("partitions:liste")
|
||||
context = self.get_context_data()
|
||||
context['sauvegarde'] = sauvegarde
|
||||
context['error'] = error
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
||||
class ConfDelete(ChefRequiredMixin, TemplateView):
|
||||
template_name = "partitions/conf_delete.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['nom'] = self.kwargs.get("nom")
|
||||
context['auteur'] = self.kwargs.get("auteur")
|
||||
context['id'] = self.kwargs.get("id")
|
||||
return context
|
||||
|
||||
|
||||
@chef_required
|
||||
def conf_delete(request, nom, auteur, id):
|
||||
part = get_object_or_404(Partition, id=id)
|
||||
return render(request, 'partitions/conf_delete.html', locals())
|
||||
class DeleteMorc(ChefRequiredMixin, TemplateView):
|
||||
model = PartitionSet
|
||||
|
||||
@chef_required
|
||||
def delete_morc(request, nom, auteur):
|
||||
p = get_object_or_404(PartitionSet, nom=nom, auteur=auteur)
|
||||
part = p.partition_set.all()
|
||||
for pa in part:
|
||||
pa.delete()
|
||||
p.delete()
|
||||
partitions = PartitionSet.objects.all()
|
||||
categories = Category.objects.prefetch_related("partitionset_set")
|
||||
return redirect('partitions:liste')
|
||||
def get(self, request, *args, **kwargs):
|
||||
p = get_object_or_404(self.model, nom=self.kwargs['nom'],
|
||||
auteur=self.kwargs['auteur'])
|
||||
part = p.partition_set.all()
|
||||
for pa in part:
|
||||
pa.delete()
|
||||
p.delete()
|
||||
return redirect("partitions:liste")
|
||||
|
||||
|
||||
@chef_required
|
||||
def conf_delete_morc(request, nom, auteur):
|
||||
return render(request, 'partitions/conf_delete_morc.html', locals())
|
||||
|
||||
class ConfDeleteMorc(ChefRequiredMixin, TemplateView):
|
||||
template_name = "partitions/conf_delete_morc.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['nom'] = self.kwargs.get("nom")
|
||||
context['auteur'] = self.kwargs.get("auteur")
|
||||
return context
|
||||
|
||||
|
||||
def download(request, nom, auteur, partition_id):
|
||||
|
||||
partition = get_object_or_404(Partition, id=partition_id)
|
||||
download_unlogged = partition.morceau.download_unlogged
|
||||
if(download_unlogged == 'o' or request.user.is_authenticated):
|
||||
with open(partition.part.path, 'rb') as f:
|
||||
if download_unlogged == "o" or request.user.is_authenticated:
|
||||
with open(partition.part.path, "rb") as f:
|
||||
myfile = File(f)
|
||||
response = HttpResponse(content=myfile.read())
|
||||
typ = os.path.splitext(myfile.name)[1][1:]
|
||||
response['Content-Type'] = 'application/%s' % (typ, )
|
||||
response['Content-Disposition'] = 'attachment; filename=%s_%s_%s.%s' % (
|
||||
slugify(nom), slugify(auteur), slugify(partition.nom), typ)
|
||||
response["Content-Type"] = "application/%s" % (typ,)
|
||||
response["Content-Disposition"] = "attachment; filename=%s_%s_%s.%s" % (
|
||||
slugify(nom),
|
||||
slugify(auteur),
|
||||
slugify(partition.nom),
|
||||
typ,
|
||||
)
|
||||
return response
|
||||
else :
|
||||
return redirect('login')
|
||||
else:
|
||||
return redirect("login")
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class TrombonoscopeConfig(AppConfig):
|
||||
name = 'trombonoscope'
|
||||
name = "trombonoscope"
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
from django import forms
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class ChangeTrombonoscope(forms.ModelForm):
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(ChangeTrombonoscope, self).save(*args, **kwargs)
|
||||
|
||||
trombonoscope = self.cleaned_data["trombonoscope"]
|
||||
|
||||
trombonoscope_colors = self.cleaned_data['trombonoscope_colors']
|
||||
if(trombonoscope_colors != 'autre'):
|
||||
|
||||
self.instance.trombonoscope_fond=trombonoscope_colors[:7]
|
||||
self.instance.trombonoscope_texte=trombonoscope_colors[7:]
|
||||
self.instance.save( )
|
||||
|
||||
trombonoscope_colors = self.cleaned_data["trombonoscope_colors"]
|
||||
if trombonoscope_colors != "autre":
|
||||
|
||||
self.instance.trombonoscope_fond = trombonoscope_colors[:7]
|
||||
self.instance.trombonoscope_texte = trombonoscope_colors[7:]
|
||||
self.instance.save()
|
||||
|
||||
class Meta:
|
||||
model = ErnestoUser
|
||||
fields = ("trombonoscope","nom_trombonoscope","instru_trombonoscope","trombonoscope_colors","trombonoscope_fond","trombonoscope_texte")
|
||||
fields = (
|
||||
"trombonoscope",
|
||||
"nom_trombonoscope",
|
||||
"instru_trombonoscope",
|
||||
"trombonoscope_colors",
|
||||
"trombonoscope_fond",
|
||||
"trombonoscope_texte",
|
||||
)
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from django import template
|
||||
from datetime import date, timedelta
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter
|
||||
def modulo(num, val):
|
||||
return num % val
|
||||
|
|
|
@ -2,10 +2,8 @@ from django.urls import path
|
|||
|
||||
from trombonoscope import views
|
||||
|
||||
|
||||
app_name = "trombonoscope"
|
||||
urlpatterns = [
|
||||
|
||||
path("", views.trombonoscope, name="view"),
|
||||
path("modif_profil", views.changetrombonoscope, name="change"),
|
||||
path("", views.Trombonoscope.as_view(), name="view"),
|
||||
path("modif_profil", views.ChangeTrombonoscope.as_view(), name="change"),
|
||||
]
|
||||
|
|
|
@ -1,24 +1,39 @@
|
|||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
from gestion.models import ErnestoUser
|
||||
from trombonoscope.forms import ChangeTrombonoscope
|
||||
from django.shortcuts import render, redirect
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.views.generic import TemplateView
|
||||
|
||||
@login_required
|
||||
def changetrombonoscope(request):
|
||||
if request.method == 'POST':
|
||||
requbis = request.POST.copy()
|
||||
form = ChangeTrombonoscope(request.POST,request.FILES, instance=request.user.profile)
|
||||
|
||||
class ChangeTrombonoscope(LoginRequiredMixin, TemplateView):
|
||||
form_class = ChangeTrombonoscope
|
||||
template_name = "trombonoscope/changetrombonoscope.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
form = self.form_class(instance=self.request.user.profile)
|
||||
context['form'] = form
|
||||
return context
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.form_class(request.POST, request.FILES,
|
||||
instance=request.user.profile)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
success = True
|
||||
return redirect('trombonoscope:view')
|
||||
else:
|
||||
form = ChangeTrombonoscope(instance=request.user.profile)
|
||||
return render(request, 'trombonoscope/changetrombonoscope.html', locals())
|
||||
return redirect("trombonoscope:view")
|
||||
context = self.get_context_data()
|
||||
context['form'] = form
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
@login_required
|
||||
def trombonoscope(request):
|
||||
trombonoscope_actuel = ErnestoUser.objects.filter(trombonoscope = "o_a")
|
||||
trombonoscope_vieux = ErnestoUser.objects.filter(trombonoscope = "o_v")
|
||||
return render(request, 'trombonoscope/trombonoscope.html', {'trombonoscope_actuel':trombonoscope_actuel,'trombonoscope_vieux':trombonoscope_vieux})
|
||||
|
||||
class Trombonoscope(LoginRequiredMixin, TemplateView):
|
||||
template_name = "trombonoscope/trombonoscope.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['trombonoscope_vieux'] = ErnestoUser.objects.filter(
|
||||
trombonoscope="o_v")
|
||||
context['trombonoscope_actuel'] = ErnestoUser.objects.filter(
|
||||
trombonoscope="o_a")
|
||||
return context
|
||||
|
|
Loading…
Reference in a new issue