From 3118264ac2d178ac12c71654d40fcb6c79cb8ed3 Mon Sep 17 00:00:00 2001 From: Fedaya Date: Fri, 23 Jan 2026 07:56:00 +0100 Subject: [PATCH] first commit --- manifeste_velo/manage.py | 22 +++ manifeste_velo/questionnaire/__init__.py | 0 manifeste_velo/questionnaire/admin.py | 12 ++ manifeste_velo/questionnaire/apps.py | 5 + .../questionnaire/migrations/0001_initial.py | 107 ++++++++++++++ .../questionnaire/migrations/__init__.py | 0 manifeste_velo/questionnaire/models.py | 78 +++++++++++ .../static/questionnaire/logo.png | Bin 0 -> 31838 bytes manifeste_velo/questionnaire/tests.py | 3 + manifeste_velo/questionnaire/urls.py | 9 ++ manifeste_velo/questionnaire/views.py | 3 + manifeste_velo/signatures/__init__.py | 0 manifeste_velo/signatures/asgi.py | 16 +++ manifeste_velo/signatures/settings.py | 131 ++++++++++++++++++ manifeste_velo/signatures/urls.py | 23 +++ manifeste_velo/signatures/wsgi.py | 16 +++ manifeste_velo/templates/admin_base.html | 88 ++++++++++++ manifeste_velo/templates/base.html | 28 ++++ 18 files changed, 541 insertions(+) create mode 100755 manifeste_velo/manage.py create mode 100644 manifeste_velo/questionnaire/__init__.py create mode 100644 manifeste_velo/questionnaire/admin.py create mode 100644 manifeste_velo/questionnaire/apps.py create mode 100644 manifeste_velo/questionnaire/migrations/0001_initial.py create mode 100644 manifeste_velo/questionnaire/migrations/__init__.py create mode 100644 manifeste_velo/questionnaire/models.py create mode 100644 manifeste_velo/questionnaire/static/questionnaire/logo.png create mode 100644 manifeste_velo/questionnaire/tests.py create mode 100644 manifeste_velo/questionnaire/urls.py create mode 100644 manifeste_velo/questionnaire/views.py create mode 100644 manifeste_velo/signatures/__init__.py create mode 100644 manifeste_velo/signatures/asgi.py create mode 100644 manifeste_velo/signatures/settings.py create mode 100644 manifeste_velo/signatures/urls.py create mode 100644 manifeste_velo/signatures/wsgi.py create mode 100644 manifeste_velo/templates/admin_base.html create mode 100644 manifeste_velo/templates/base.html diff --git a/manifeste_velo/manage.py b/manifeste_velo/manage.py new file mode 100755 index 0000000..07c1bc1 --- /dev/null +++ b/manifeste_velo/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'signatures.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/manifeste_velo/questionnaire/__init__.py b/manifeste_velo/questionnaire/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manifeste_velo/questionnaire/admin.py b/manifeste_velo/questionnaire/admin.py new file mode 100644 index 0000000..4fb097d --- /dev/null +++ b/manifeste_velo/questionnaire/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin + +from questionnaire import models + +# Register your models here. + +admin.site.register(models.Ville) +admin.site.register(models.PointManifeste) +admin.site.register(models.Liste) +admin.site.register(models.Candidat) +admin.site.register(models.ReponseListe) +admin.site.register(models.ReponseListeItem) diff --git a/manifeste_velo/questionnaire/apps.py b/manifeste_velo/questionnaire/apps.py new file mode 100644 index 0000000..53e842e --- /dev/null +++ b/manifeste_velo/questionnaire/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class QuestionnaireConfig(AppConfig): + name = 'questionnaire' diff --git a/manifeste_velo/questionnaire/migrations/0001_initial.py b/manifeste_velo/questionnaire/migrations/0001_initial.py new file mode 100644 index 0000000..35ad264 --- /dev/null +++ b/manifeste_velo/questionnaire/migrations/0001_initial.py @@ -0,0 +1,107 @@ +# Generated by Django 6.0.1 on 2026-01-23 07:26 + +import django.db.models.deletion +import django_extensions.db.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Candidat', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')), + ('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')), + ('nom', models.CharField(max_length=255)), + ('prenom', models.CharField(max_length=255, verbose_name='Prénom')), + ], + options={ + 'get_latest_by': 'modified', + 'abstract': False, + }, + ), + migrations.CreateModel( + name='PointManifeste', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('titre', models.CharField(max_length=255)), + ('texte', models.TextField()), + ('exemple', models.TextField(blank=True, null=True)), + ('ordre', models.PositiveSmallIntegerField()), + ('est_commun', models.BooleanField(verbose_name="Item commun à l'agglo")), + ], + options={ + 'ordering': ['ordre'], + }, + ), + migrations.CreateModel( + name='Ville', + fields=[ + ('nom', models.CharField(max_length=255, unique=True)), + ('slug', django_extensions.db.fields.AutoSlugField(blank=True, editable=False, populate_from=['nom'])), + ('code_insee', models.PositiveSmallIntegerField(primary_key=True, serialize=False, verbose_name='Code INSEE')), + ], + ), + migrations.CreateModel( + name='Liste', + fields=[ + ('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')), + ('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')), + ('uuid', models.UUIDField(primary_key=True, serialize=False)), + ('nom', models.CharField(max_length=255)), + ('email', models.CharField(max_length=255, verbose_name='Adresse E-Mail')), + ('telephone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Numéro de Téléphone')), + ('site_internet', models.CharField(max_length=255, verbose_name='Site internet')), + ('email_ouvert', models.DateTimeField(blank=True, null=True, verbose_name="L'e-mail au candidat a été ouvert")), + ('responsable_mobilites', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='questionnaire.candidat', verbose_name='Responsable mobilités de la liste')), + ('tete_liste', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='liste_menee', to='questionnaire.candidat', verbose_name='Tete de liste')), + ('ville', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='questionnaire.ville')), + ], + options={ + 'ordering': ['ville', 'nom'], + }, + ), + migrations.CreateModel( + name='ReponseListe', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')), + ('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')), + ('expression_libre', models.TextField(verbose_name='Expression libre')), + ('email_confirmation', models.BooleanField(verbose_name='E-mail de confirmation envoyé')), + ('finalise', models.BooleanField(verbose_name='Réponse finalisée')), + ('liste', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, to='questionnaire.liste')), + ], + options={ + 'get_latest_by': 'modified', + 'abstract': False, + }, + ), + migrations.CreateModel( + name='ReponseListeItem', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')), + ('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')), + ('engagement', models.CharField(choices=[('oui', 'oui'), ('en partie', 'en partie'), ('non', 'non')], max_length=9)), + ('explication', models.TextField()), + ('point', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='questionnaire.pointmanifeste')), + ], + options={ + 'get_latest_by': 'modified', + 'abstract': False, + }, + ), + migrations.AddField( + model_name='pointmanifeste', + name='ville', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='questionnaire.ville'), + ), + ] diff --git a/manifeste_velo/questionnaire/migrations/__init__.py b/manifeste_velo/questionnaire/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manifeste_velo/questionnaire/models.py b/manifeste_velo/questionnaire/models.py new file mode 100644 index 0000000..d2b672c --- /dev/null +++ b/manifeste_velo/questionnaire/models.py @@ -0,0 +1,78 @@ +from django.db import models +from django_extensions.db.fields import AutoSlugField +from django_extensions.db.models import TimeStampedModel + +# Create your models here. + + +class Ville(models.Model): + nom = models.CharField(max_length=255, unique=True) + slug = AutoSlugField(populate_from=["nom"]) + code_insee = models.PositiveSmallIntegerField(verbose_name="Code INSEE", primary_key=True) + + def __str__(self): + return f"{self.nom} ({self.code_insee})" + + +class PointManifeste(models.Model): + titre = models.CharField(max_length=255) + texte = models.TextField() + exemple = models.TextField(null=True, blank=True) + ordre = models.PositiveSmallIntegerField() + est_commun = models.BooleanField(verbose_name="Item commun à l'agglo") + ville = models.ForeignKey(Ville, on_delete=models.PROTECT, null=True, blank=True) + + def __str__(self): + return f"{self.ordre}. {self.titre}" + (f" (pour {self.ville.nom})" if self.ville is not None else "") + + class Meta: + ordering = ["ordre"] + + +class Candidat(TimeStampedModel, models.Model): + nom = models.CharField(max_length=255) + prenom = models.CharField(max_length=255, verbose_name="Prénom") + + def __str__(self): + return f"{self.prenom} {self.nom} - {self.ville.nom}" + + +class Liste(TimeStampedModel, models.Model): + uuid = models.UUIDField(primary_key=True) + nom = models.CharField(max_length=255) + email = models.CharField(max_length=255, verbose_name="Adresse E-Mail") + telephone = models.CharField(max_length=255, verbose_name="Numéro de Téléphone", blank=True, null=True) + site_internet = models.CharField(max_length=255, verbose_name="Site internet") + ville = models.ForeignKey(Ville, on_delete=models.PROTECT) + tete_liste = models.OneToOneField( + Candidat, on_delete=models.PROTECT, related_name="liste_menee", verbose_name="Tete de liste" + ) + responsable_mobilites = models.OneToOneField( + Candidat, on_delete=models.PROTECT, verbose_name="Responsable mobilités de la liste" + ) + email_ouvert = models.DateTimeField(blank=True, null=True, verbose_name="L'e-mail au candidat a été ouvert") + + def __str__(self): + return f"{self.nom} - {self.ville.nom} - {self.tete_liste.prenom} {self.tete_liste.nom}" + + class Meta: + ordering = ["ville", "nom"] + + +class ReponseListe(TimeStampedModel, models.Model): + liste = models.OneToOneField(Liste, on_delete=models.PROTECT) + expression_libre = models.TextField(verbose_name="Expression libre") + email_confirmation = models.BooleanField(verbose_name="E-mail de confirmation envoyé") + finalise = models.BooleanField(verbose_name="Réponse finalisée") + + +class EngagementChoices(models.TextChoices): + OUI = "oui", "oui" + EN_PARTIE = "en partie", "en partie" + NON = "non", "non" + + +class ReponseListeItem(TimeStampedModel, models.Model): + point = models.ForeignKey(PointManifeste, on_delete=models.PROTECT) + engagement = models.CharField(max_length=9, choices=EngagementChoices.choices) + explication = models.TextField() diff --git a/manifeste_velo/questionnaire/static/questionnaire/logo.png b/manifeste_velo/questionnaire/static/questionnaire/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f4a5fabbccf59d89da88d26e82c1c02a3bd2998a GIT binary patch literal 31838 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 V$X8!48{e0F%StLq)QFjc{6AAPGhhG! literal 0 HcmV?d00001 diff --git a/manifeste_velo/questionnaire/tests.py b/manifeste_velo/questionnaire/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/manifeste_velo/questionnaire/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/manifeste_velo/questionnaire/urls.py b/manifeste_velo/questionnaire/urls.py new file mode 100644 index 0000000..034b476 --- /dev/null +++ b/manifeste_velo/questionnaire/urls.py @@ -0,0 +1,9 @@ +from django.contrib.auth.views import LoginView, LogoutView +from django.urls import path + +app_name = "questionnaire" + +urlpatterns = [ + path("login", LoginView.as_view(template_name="questionnaire/login.html"), name="login"), + path("logout", LogoutView.as_view(template_name="questionnaire/logout.html"), name="logout"), +] diff --git a/manifeste_velo/questionnaire/views.py b/manifeste_velo/questionnaire/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/manifeste_velo/questionnaire/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/manifeste_velo/signatures/__init__.py b/manifeste_velo/signatures/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/manifeste_velo/signatures/asgi.py b/manifeste_velo/signatures/asgi.py new file mode 100644 index 0000000..085e96f --- /dev/null +++ b/manifeste_velo/signatures/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for signatures project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'signatures.settings') + +application = get_asgi_application() diff --git a/manifeste_velo/signatures/settings.py b/manifeste_velo/signatures/settings.py new file mode 100644 index 0000000..98a21ac --- /dev/null +++ b/manifeste_velo/signatures/settings.py @@ -0,0 +1,131 @@ +""" +Django settings for signatures project. + +Generated by 'django-admin startproject' using Django 6.0.1. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/6.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-se*^9ys917tep!txqkoa8(2kfigkya9nh2tynmoxn8^+s8c@9j' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django_node_assets', + 'django_extensions', + 'questionnaire' +] + +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', +] + +ROOT_URLCONF = 'signatures.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ BASE_DIR / 'templates'], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'signatures.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/6.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/6.0/topics/i18n/ + +LANGUAGE_CODE = 'fr-fr' + +TIME_ZONE = 'Europe/Paris' + +USE_I18N = True + +USE_TZ = False + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/6.0/howto/static-files/ + +STATIC_URL = 'static/' +STATIC_ROOT = BASE_DIR / "static" +STATICFILES_FINDERS = [ + "django.contrib.staticfiles.finders.FileSystemFinder", + "django.contrib.staticfiles.finders.AppDirectoriesFinder", + "django_node_assets.finders.NodeModulesFinder", +] +MEDIA_URL = "media/" +MEDIA_ROOT = BASE_DIR / "media" + +NODE_PACKAGE_JSON = BASE_DIR / "package.json" +NODE_MODULES_ROOT = BASE_DIR / "node_modules" diff --git a/manifeste_velo/signatures/urls.py b/manifeste_velo/signatures/urls.py new file mode 100644 index 0000000..2913b1b --- /dev/null +++ b/manifeste_velo/signatures/urls.py @@ -0,0 +1,23 @@ +""" +URL configuration for signatures project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/6.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +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 + +urlpatterns = [ + path('', include('questionnaire.urls')), + path('django-admin/', admin.site.urls), +] diff --git a/manifeste_velo/signatures/wsgi.py b/manifeste_velo/signatures/wsgi.py new file mode 100644 index 0000000..91dac09 --- /dev/null +++ b/manifeste_velo/signatures/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for signatures project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'signatures.settings') + +application = get_wsgi_application() diff --git a/manifeste_velo/templates/admin_base.html b/manifeste_velo/templates/admin_base.html new file mode 100644 index 0000000..c7b2899 --- /dev/null +++ b/manifeste_velo/templates/admin_base.html @@ -0,0 +1,88 @@ +{% extends 'base.html' %}{% load static %}{% load simple_menu %} +{% block body %}{% generate_menu %} +
+ +
+ +
+ {% block admin_body %} + {% endblock %} +
+
+
+{% endblock %} +{% block javascripts_footer %} +{{ block.super }} + +{% endblock %} \ No newline at end of file diff --git a/manifeste_velo/templates/base.html b/manifeste_velo/templates/base.html new file mode 100644 index 0000000..4861f06 --- /dev/null +++ b/manifeste_velo/templates/base.html @@ -0,0 +1,28 @@ +{% load static %} + + + {% block title %}Place au Vélo Angers{% endblock %} + + + {% block css %} + + + + {% endblock %} + {% block javascripts_header %}{% endblock %} + + + {% block body %} + + {% endblock %} + {% block javascripts_footer %} + + + + {% endblock %} + + \ No newline at end of file