Compare commits
25 Commits
refactorin
...
main
Author | SHA1 | Date |
---|---|---|
Trullemans Gregory | e61279b75b | |
Trullemans Gregory | 796ccc3f09 | |
Trullemans Gregory | c38c72d637 | |
Trullemans Gregory | 16486064ce | |
Trullemans Gregory | 0cb1a81215 | |
Trullemans Gregory | 3b1862f9f6 | |
Fred Pauchet | 8b9e61ed2d | |
Fred Pauchet | 359c215924 | |
Fred Pauchet | 76eb02585b | |
Fred Pauchet | 4d095fab31 | |
Fred Pauchet | 9381ebc593 | |
Fred Pauchet | f409ce4cc5 | |
Fred Pauchet | f057380fdb | |
Fred Pauchet | 3d919c7edf | |
Fred Pauchet | fe4d2c620e | |
Fred Pauchet | 046755d987 | |
Fred Pauchet | 54695787de | |
Fred Pauchet | 7bba598ab0 | |
Fred Pauchet | ee2608d820 | |
Fred Pauchet | dcb5cd0e9d | |
Fred Pauchet | b700ca8b10 | |
Fred Pauchet | f278d4befa | |
Fred Pauchet | 91ee5cdc65 | |
Fred Pauchet | 8e9b4b8aa7 | |
Fred Pauchet | e56660e626 |
|
@ -232,7 +232,7 @@ single-line-if-stmt=no
|
|||
|
||||
[VARIABLES]
|
||||
|
||||
django-settings-module=khana.settings
|
||||
django-settings-module=config.settings
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid defining new builtins when possible.
|
||||
|
|
19
Makefile
19
Makefile
|
@ -1,13 +1,14 @@
|
|||
#!/bin/bash
|
||||
# Makefile for khana
|
||||
|
||||
.PHONY: coverage errors
|
||||
ifeq ($(shell which coverage >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The 'coverage' command was not found. Make sure you have coverage installed)
|
||||
endif
|
||||
|
||||
.PHONY: help coverage
|
||||
|
||||
help:
|
||||
@echo " coverage to run coverage check of the source files."
|
||||
|
||||
coverage:
|
||||
cd src/; coverage run --source='.' manage.py test; coverage report -m; cd ..
|
||||
coverage run --source='.' manage.py test; coverage report; coverage html;
|
||||
@echo "Testing of coverage in the sources finished."
|
||||
|
||||
lint:
|
||||
pylint src/* --disable=django-not-configured
|
||||
|
||||
errors:
|
||||
pylint src/* --errors-only --disable=django-not-configured
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
-- phpMyAdmin SQL Dump
|
||||
-- version 4.4.12
|
||||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Client : localhost
|
||||
-- Généré le : Mer 18 Juillet 2018 à 14:32
|
||||
-- Version du serveur : 5.6.26
|
||||
-- Version de PHP : 7.1.16
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Base de données : `ffg_judging`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `competition_availablecategory`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `competition_availablecategory` (
|
||||
`id` int(11) NOT NULL,
|
||||
`is_active` tinyint(1) NOT NULL,
|
||||
`category_id` int(11) DEFAULT NULL,
|
||||
`division_id` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Contenu de la table `competition_availablecategory`
|
||||
--
|
||||
|
||||
INSERT INTO `competition_availablecategory` (`id`, `is_active`, `category_id`, `division_id`) VALUES
|
||||
(1, 1, 1, 5),
|
||||
(2, 1, 2, 5),
|
||||
(3, 1, 3, 5),
|
||||
(4, 1, 4, 1),
|
||||
(5, 1, 5, 1),
|
||||
(6, 1, 6, 1),
|
||||
(7, 1, 7, 1),
|
||||
(8, 1, 8, 1),
|
||||
(9, 1, 4, 2),
|
||||
(10, 1, 5, 2),
|
||||
(11, 1, 6, 2),
|
||||
(12, 1, 7, 2),
|
||||
(13, 1, 8, 2),
|
||||
(14, 1, 9, 3),
|
||||
(15, 1, 10, 3),
|
||||
(16, 1, 11, 3),
|
||||
(17, 1, 12, 3),
|
||||
(18, 1, 13, 4);
|
||||
|
||||
--
|
||||
-- Index pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Index pour la table `competition_availablecategory`
|
||||
--
|
||||
ALTER TABLE `competition_availablecategory`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD UNIQUE KEY `competition_availablecat_division_id_category_id_7cbea8cc_uniq` (`division_id`,`category_id`),
|
||||
ADD KEY `competition_availabl_category_id_d9b4ab8c_fk_competiti` (`category_id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `competition_availablecategory`
|
||||
--
|
||||
ALTER TABLE `competition_availablecategory`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=19;
|
||||
--
|
||||
-- Contraintes pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Contraintes pour la table `competition_availablecategory`
|
||||
--
|
||||
ALTER TABLE `competition_availablecategory`
|
||||
ADD CONSTRAINT `competition_availabl_category_id_d9b4ab8c_fk_competiti` FOREIGN KEY (`category_id`) REFERENCES `competition_category` (`id`),
|
||||
ADD CONSTRAINT `competition_availabl_division_id_88e96c01_fk_competiti` FOREIGN KEY (`division_id`) REFERENCES `competition_division` (`id`);
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
@ -1,76 +0,0 @@
|
|||
-- phpMyAdmin SQL Dump
|
||||
-- version 4.4.12
|
||||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Client : localhost
|
||||
-- Généré le : Mer 18 Juillet 2018 à 14:31
|
||||
-- Version du serveur : 5.6.26
|
||||
-- Version de PHP : 7.1.16
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Base de données : `ffg_judging`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `competition_category`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `competition_category` (
|
||||
`id` int(11) NOT NULL,
|
||||
`label` varchar(25) NOT NULL,
|
||||
`acronym` varchar(7) NOT NULL,
|
||||
`is_active` tinyint(1) NOT NULL
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Contenu de la table `competition_category`
|
||||
--
|
||||
|
||||
INSERT INTO `competition_category` (`id`, `label`, `acronym`, `is_active`) VALUES
|
||||
(1, '-8 ans', '-8', 1),
|
||||
(2, '-9 ans', '-9', 1),
|
||||
(3, '-10 ans', '-10', 1),
|
||||
(4, '11 ans', '11', 1),
|
||||
(5, '12 ans', '12', 1),
|
||||
(6, '13-14 ans', '13-14', 1),
|
||||
(7, 'Juniors', 'Ju', 1),
|
||||
(8, 'Seniors', 'Se', 1),
|
||||
(9, 'Niveau 1', 'N1', 1),
|
||||
(10, 'Niveau 2', 'N2', 1),
|
||||
(11, 'Niveau 3', 'N3', 1),
|
||||
(12, 'Niveau 4', 'N4', 1),
|
||||
(13, 'Bronze', 'Bronze', 1);
|
||||
|
||||
--
|
||||
-- Index pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Index pour la table `competition_category`
|
||||
--
|
||||
ALTER TABLE `competition_category`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `competition_category`
|
||||
--
|
||||
ALTER TABLE `competition_category`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=14;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
@ -1,62 +0,0 @@
|
|||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Base de données : `ffg_judging`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `competition_division`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `competition_division` (
|
||||
`id` int(11) NOT NULL,
|
||||
`label` varchar(25) NOT NULL,
|
||||
`acronym` varchar(5) NOT NULL,
|
||||
`is_active` tinyint(1) NOT NULL
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Contenu de la table `competition_division`
|
||||
--
|
||||
|
||||
INSERT INTO `competition_division` (`id`, `label`, `acronym`, `is_active`) VALUES
|
||||
(1, 'Division 1', 'D1', 1),
|
||||
(2, 'Division 2', 'D2', 1),
|
||||
(3, 'Division 3', 'D3', 1),
|
||||
(4, 'Division 4', 'D4', 1),
|
||||
(5, 'Division Préparatoire', 'Prépa', 1);
|
||||
|
||||
--
|
||||
-- Index pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Index pour la table `competition_division`
|
||||
--
|
||||
ALTER TABLE `competition_division`
|
||||
ADD PRIMARY KEY (`id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `competition_division`
|
||||
--
|
||||
ALTER TABLE `competition_division`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
|
@ -1,66 +0,0 @@
|
|||
"1","Delginiesse","Lou","Acrotramp Blocry","2007-05-30","F","121510","1","64","17"
|
||||
"2","Delginiesse","Léa","Acrotramp Blocry","2004-04-01","F","121509","1","24","17"
|
||||
"3","Gatelier","Léa","Acrotramp Blocry","2005-09-22","F","141305","1","51","17"
|
||||
"4","Henry","Océane","Acrotramp Blocry","2003-05-26","F","99539","1","20","17"
|
||||
"5","Herlant","Pénéline","Acrotramp Blocry","2006-08-30","F","122578","1","40","17"
|
||||
"6","Reynaert","Sara","Acrotramp Blocry","2006-02-22","F","122573","1","61","17"
|
||||
"7","Trejo","Metzli","Acrotramp Blocry","2004-06-17","F","141308","1","18","17"
|
||||
"8","Beauclercq","Nathan","Acrotramp Blocry","2005-01-22","M","141301","1","17","17"
|
||||
"9","De Mesmaeker","Adrien","Acrotramp Blocry","2004-04-09","M","122585","1","33","17"
|
||||
"10","Detalle","Mattéo","Acrotramp Blocry","2006-10-25","M","122588","1","26","17"
|
||||
"11","Garcia Moreau","Matéo","Acrotramp Blocry","2005-08-24","M","99555","1","37","17"
|
||||
"12","Jarman","Joshua","Acrotramp Blocry","2006-01-10","M","141315","1","11","17"
|
||||
"13","Pablos Martin","Hugo","Acrotramp Blocry","2004-08-12","M","141313","1","34","17"
|
||||
"14","Van Poucke Cotton","Nelson","Acrotramp Blocry","2007-01-23","M","141306","1","57","17"
|
||||
"15","Vanhuffel","Trystan","Acrotramp Blocry","2005-04-03","M","141303","1","21","17"
|
||||
"16","Ingels","Cedric","CGOM ASBL","2007-06-08","M","82832","1","44","17"
|
||||
"17","Charles","Angelique","Acrotramp Blocry","1992-08-10","F","10900","1","5","16"
|
||||
"18","Leblanc","Olivia","Acrotramp Blocry","2000-12-19","F","112449","1","59","16"
|
||||
"19","Luyten","Clara","Acrotramp Blocry","2003-07-23","F","112450","1","56","16"
|
||||
"20","Tombeux","Juliette","Acrotramp Blocry","2005-12-28","F","99545","1","14","16"
|
||||
"21","Eglem","Elisa","Aquilon Lillois","2005-02-24","F","133827","1","27","16"
|
||||
"22","Geirnaert","Marine","Aquilon Lillois","2002-11-12","F","74759","1","13","16"
|
||||
"23","Kraled","Anyssa","Aquilon Lillois","2004-10-18","F","96489","1","1","16"
|
||||
"24","Catteau","Marine","CGOM ASBL","2004-02-05","F","135223","1","36","16"
|
||||
"25","Gaeremynck","Laurine","CGOM ASBL","2002-03-01","F","10012","1","31","16"
|
||||
"26","Ernaelsten","Perrine","TRAMPO NAMUR CLUB","2004-12-09","F","54365","1","4","16"
|
||||
"27","Brodzinski","Barthélemy","Acrotramp Blocry","2002-06-24","M","58261","1","49","16"
|
||||
"28","Goens","François","Acrotramp Blocry","2001-08-27","M","141309","1","29","16"
|
||||
"29","Le Grelle","Jérémie","Acrotramp Blocry","2000-10-24","M","96217","1","39","16"
|
||||
"30","Simon","Matthias","Acrotramp Blocry","2003-02-24","M","122574","1","60","16"
|
||||
"31","Devos","Hugo","CGOM ASBL","2006-05-22","M","133688","1","28","16"
|
||||
"32","Dhulst","Louis","CGOM ASBL","2006-09-27","M","127026","1","54","16"
|
||||
"33","Jeunehomme","Nathan","TRAMPO NAMUR CLUB","2003-03-05","M","126730","1","23","16"
|
||||
"34","Breugelmans","Baptiste","Acrotramp Blocry","2002-10-21","M","122559","1","53","15"
|
||||
"35","Huwaerts","Leslie","Acrotramp Blocry","2001-12-08","F","71725","1","48","15"
|
||||
"36","Gheysens","Julie","CGOM ASBL","2005-06-01","F","42242","1","2","15"
|
||||
"37","Herpoel","Cyrielle","CGOM ASBL","2005-10-28","F","69829","1","43","15"
|
||||
"38","Platteau Holvoet","Raphael","CGOM ASBL","2005-02-25","M","120509","1","45","15"
|
||||
"39","Roussel","Leina","CGOM ASBL","2004-03-17","F","80890","1","3","18"
|
||||
"40","Vanbiervliet","Zoë","CGOM ASBL","2000-12-11","F","10216","1","47","14"
|
||||
"41","Vandenberghe","Zélie","CGOM ASBL","2003-08-07","F","42230","1","41","14"
|
||||
"42","Jacquet","Quentin","Acrotramp Blocry","2004-10-19","M","99547","1","66","14"
|
||||
"43","Moens","Aymeric","Acrotramp Blocry","2001-02-26","M","58294","1","65","12"
|
||||
"44","Debusschere","Tom","CGOM ASBL","2003-02-11","M","91937","1","8","14"
|
||||
"45","Jaillet","Robin","CGOM ASBL","2001-06-29","M","97949","1","25","14"
|
||||
"46","Scokart","Romain","Flying Acrobatics Trampoline Club","2001-12-30","M","103263","1","42","14"
|
||||
"47","Herlant","Ophéliane","Acrotramp Blocry","2008-11-03","F","122577","1","15","3"
|
||||
"48","Lannoye","Cédric","Acrotramp Blocry","2008-06-30","M","141316","1","38","3"
|
||||
"49","May","boris","Acrotramp Blocry","2008-06-17","M","144052","1","12","3"
|
||||
"50","Mean","Juliette","Acrotramp Blocry","2008-02-05","F","54451","1","35","3"
|
||||
"51","Reynart","Flore","Acrotramp Blocry","2008-07-15","F","141297","1","46","3"
|
||||
"52","Romain","Mathis","Acrotramp Blocry","2008-02-28","M","141307","1","50","3"
|
||||
"53","Cordier","Jeanne","Acrotramp Blocry","2010-01-10","F","144055","1","58","2"
|
||||
"54","Demaret","Louise","Acrotramp Blocry","2009-09-27","F","96169","1","6","2"
|
||||
"55","Ebertitan","Kenza","Acrotramp Blocry","2009-06-26","F","141304","1","55","2"
|
||||
"56","Halin","Axel","Acrotramp Blocry","2009-02-13","M","141310","1","9","2"
|
||||
"57","Renette","Zebulon","Acrotramp Blocry","2009-02-14","M","141317","1","63","2"
|
||||
"58","Mertens","Déborah","Flying Acrobatics Trampoline Club","2009-11-04","F","119801","1","16","2"
|
||||
"59","Salhi","Safwane","Flying Acrobatics Trampoline Club","2001-05-30","M","4283","1","30","7"
|
||||
"60","Pesesse","Lucas","Flying Acrobatics Trampoline Club","2007-07-19","M","70414","1","32","4"
|
||||
"61","Carlini","Gabriel","Flying Acrobatics Trampoline Club","2006-08-11","M","103673","1","22","5"
|
||||
"62","Demacker","Naomy","CGOM ASBL","2004-04-14","F","123439","1","10","11"
|
||||
"63","Damri","Neila","TRAMPO NAMUR CLUB","2004-06-14","F","25026","1","62","11"
|
||||
"64","Granda Martinez","Noelia","Flying Acrobatics Trampoline Club","2003-01-28","F","66196","1","52","12"
|
||||
"65","Vanholder","Noah","Flying Acrobatics Trampoline Club","2003-05-21","M","101994","1","7","12"
|
||||
"66","Pirson","Maxime","TRAMPO NAMUR CLUB","2000-11-08","M","24332","1","19","13"
|
|
|
@ -1,146 +0,0 @@
|
|||
-- phpMyAdmin SQL Dump
|
||||
-- version 4.4.12
|
||||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Client : localhost
|
||||
-- Généré le : Mar 24 Juillet 2018 à 21:42
|
||||
-- Version du serveur : 5.6.26
|
||||
-- Version de PHP : 7.1.16
|
||||
|
||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||
SET time_zone = "+00:00";
|
||||
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8mb4 */;
|
||||
|
||||
--
|
||||
-- Base de données : `ffg_judging`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Structure de la table `person_gymnast`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `person_gymnast` (
|
||||
`id` int(11) NOT NULL,
|
||||
`lastname` varchar(255) NOT NULL,
|
||||
`firstname` varchar(255) NOT NULL,
|
||||
`club` varchar(255) NOT NULL,
|
||||
`birthdate` date NOT NULL,
|
||||
`gender` varchar(1) NOT NULL,
|
||||
`licence` int(11) DEFAULT NULL,
|
||||
`is_present` tinyint(1) NOT NULL,
|
||||
`bib` int(11) DEFAULT NULL,
|
||||
`category_id` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=67 DEFAULT CHARSET=utf8;
|
||||
|
||||
--
|
||||
-- Contenu de la table `person_gymnast`
|
||||
--
|
||||
|
||||
INSERT INTO `person_gymnast` (`id`, `lastname`, `firstname`, `club`, `birthdate`, `gender`, `licence`, `is_present`, `bib`, `category_id`) VALUES
|
||||
(1, 'Delginiesse', 'Lou', 'Acrotramp Blocry', '2007-05-30', 'F', 121510, 1, 64, 17),
|
||||
(2, 'Delginiesse', 'Léa', 'Acrotramp Blocry', '2004-04-01', 'F', 121509, 1, 24, 17),
|
||||
(3, 'Gatelier', 'Léa', 'Acrotramp Blocry', '2005-09-22', 'F', 141305, 1, 51, 17),
|
||||
(4, 'Henry', 'Océane', 'Acrotramp Blocry', '2003-05-26', 'F', 99539, 1, 20, 17),
|
||||
(5, 'Herlant', 'Pénéline', 'Acrotramp Blocry', '2006-08-30', 'F', 122578, 1, 40, 17),
|
||||
(6, 'Reynaert', 'Sara', 'Acrotramp Blocry', '2006-02-22', 'F', 122573, 1, 61, 17),
|
||||
(7, 'Trejo', 'Metzli', 'Acrotramp Blocry', '2004-06-17', 'F', 141308, 1, 18, 17),
|
||||
(8, 'Beauclercq', 'Nathan', 'Acrotramp Blocry', '2005-01-22', 'M', 141301, 1, 17, 17),
|
||||
(9, 'De Mesmaeker', 'Adrien', 'Acrotramp Blocry', '2004-04-09', 'M', 122585, 1, 33, 17),
|
||||
(10, 'Detalle', 'Mattéo', 'Acrotramp Blocry', '2006-10-25', 'M', 122588, 1, 26, 17),
|
||||
(11, 'Garcia Moreau', 'Matéo', 'Acrotramp Blocry', '2005-08-24', 'M', 99555, 1, 37, 17),
|
||||
(12, 'Jarman', 'Joshua', 'Acrotramp Blocry', '2006-01-10', 'M', 141315, 1, 11, 17),
|
||||
(13, 'Pablos Martin', 'Hugo', 'Acrotramp Blocry', '2004-08-12', 'M', 141313, 1, 34, 17),
|
||||
(14, 'Van Poucke Cotton', 'Nelson', 'Acrotramp Blocry', '2007-01-23', 'M', 141306, 1, 57, 17),
|
||||
(15, 'Vanhuffel', 'Trystan', 'Acrotramp Blocry', '2005-04-03', 'M', 141303, 1, 21, 17),
|
||||
(16, 'Ingels', 'Cedric', 'CGOM ASBL', '2007-06-08', 'M', 82832, 1, 44, 17),
|
||||
(17, 'Charles', 'Angelique', 'Acrotramp Blocry', '1992-08-10', 'F', 10900, 1, 5, 16),
|
||||
(18, 'Leblanc', 'Olivia', 'Acrotramp Blocry', '2000-12-19', 'F', 112449, 1, 59, 16),
|
||||
(19, 'Luyten', 'Clara', 'Acrotramp Blocry', '2003-07-23', 'F', 112450, 1, 56, 16),
|
||||
(20, 'Tombeux', 'Juliette', 'Acrotramp Blocry', '2005-12-28', 'F', 99545, 1, 14, 16),
|
||||
(21, 'Eglem', 'Elisa', 'Aquilon Lillois', '2005-02-24', 'F', 133827, 1, 27, 16),
|
||||
(22, 'Geirnaert', 'Marine', 'Aquilon Lillois', '2002-11-12', 'F', 74759, 1, 13, 16),
|
||||
(23, 'Kraled', 'Anyssa', 'Aquilon Lillois', '2004-10-18', 'F', 96489, 1, 1, 16),
|
||||
(24, 'Catteau', 'Marine', 'CGOM ASBL', '2004-02-05', 'F', 135223, 1, 36, 16),
|
||||
(25, 'Gaeremynck', 'Laurine', 'CGOM ASBL', '2002-03-01', 'F', 10012, 1, 31, 16),
|
||||
(26, 'Ernaelsten', 'Perrine', 'TRAMPO NAMUR CLUB', '2004-12-09', 'F', 54365, 1, 4, 16),
|
||||
(27, 'Brodzinski', 'Barthélemy', 'Acrotramp Blocry', '2002-06-24', 'M', 58261, 1, 49, 16),
|
||||
(28, 'Goens', 'François', 'Acrotramp Blocry', '2001-08-27', 'M', 141309, 1, 29, 16),
|
||||
(29, 'Le Grelle', 'Jérémie', 'Acrotramp Blocry', '2000-10-24', 'M', 96217, 1, 39, 16),
|
||||
(30, 'Simon', 'Matthias', 'Acrotramp Blocry', '2003-02-24', 'M', 122574, 1, 60, 16),
|
||||
(31, 'Devos', 'Hugo', 'CGOM ASBL', '2006-05-22', 'M', 133688, 1, 28, 16),
|
||||
(32, 'Dhulst', 'Louis', 'CGOM ASBL', '2006-09-27', 'M', 127026, 1, 54, 16),
|
||||
(33, 'Jeunehomme', 'Nathan', 'TRAMPO NAMUR CLUB', '2003-03-05', 'M', 126730, 1, 23, 16),
|
||||
(34, 'Breugelmans', 'Baptiste', 'Acrotramp Blocry', '2002-10-21', 'M', 122559, 1, 53, 15),
|
||||
(35, 'Huwaerts', 'Leslie', 'Acrotramp Blocry', '2001-12-08', 'F', 71725, 1, 48, 15),
|
||||
(36, 'Gheysens', 'Julie', 'CGOM ASBL', '2005-06-01', 'F', 42242, 1, 2, 15),
|
||||
(37, 'Herpoel', 'Cyrielle', 'CGOM ASBL', '2005-10-28', 'F', 69829, 1, 43, 15),
|
||||
(38, 'Platteau Holvoet', 'Raphael', 'CGOM ASBL', '2005-02-25', 'M', 120509, 1, 45, 15),
|
||||
(39, 'Roussel', 'Leina', 'CGOM ASBL', '2004-03-17', 'F', 80890, 1, 3, 18),
|
||||
(40, 'Vanbiervliet', 'Zoë', 'CGOM ASBL', '2000-12-11', 'F', 10216, 1, 47, 14),
|
||||
(41, 'Vandenberghe', 'Zélie', 'CGOM ASBL', '2003-08-07', 'F', 42230, 1, 41, 14),
|
||||
(42, 'Jacquet', 'Quentin', 'Acrotramp Blocry', '2004-10-19', 'M', 99547, 1, 66, 14),
|
||||
(43, 'Moens', 'Aymeric', 'Acrotramp Blocry', '2001-02-26', 'M', 58294, 1, 65, 12),
|
||||
(44, 'Debusschere', 'Tom', 'CGOM ASBL', '2003-02-11', 'M', 91937, 1, 8, 14),
|
||||
(45, 'Jaillet', 'Robin', 'CGOM ASBL', '2001-06-29', 'M', 97949, 1, 25, 14),
|
||||
(46, 'Scokart', 'Romain', 'Flying Acrobatics Trampoline Club', '2001-12-30', 'M', 103263, 1, 42, 14),
|
||||
(47, 'Herlant', 'Ophéliane', 'Acrotramp Blocry', '2008-11-03', 'F', 122577, 1, 15, 3),
|
||||
(48, 'Lannoye', 'Cédric', 'Acrotramp Blocry', '2008-06-30', 'M', 141316, 1, 38, 3),
|
||||
(49, 'May', 'boris', 'Acrotramp Blocry', '2008-06-17', 'M', 144052, 1, 12, 3),
|
||||
(50, 'Mean', 'Juliette', 'Acrotramp Blocry', '2008-02-05', 'F', 54451, 1, 35, 3),
|
||||
(51, 'Reynart', 'Flore', 'Acrotramp Blocry', '2008-07-15', 'F', 141297, 1, 46, 3),
|
||||
(52, 'Romain', 'Mathis', 'Acrotramp Blocry', '2008-02-28', 'M', 141307, 1, 50, 3),
|
||||
(53, 'Cordier', 'Jeanne', 'Acrotramp Blocry', '2010-01-10', 'F', 144055, 1, 58, 2),
|
||||
(54, 'Demaret', 'Louise', 'Acrotramp Blocry', '2009-09-27', 'F', 96169, 1, 6, 2),
|
||||
(55, 'Ebertitan', 'Kenza', 'Acrotramp Blocry', '2009-06-26', 'F', 141304, 1, 55, 2),
|
||||
(56, 'Halin', 'Axel', 'Acrotramp Blocry', '2009-02-13', 'M', 141310, 1, 9, 2),
|
||||
(57, 'Renette', 'Zebulon', 'Acrotramp Blocry', '2009-02-14', 'M', 141317, 1, 63, 2),
|
||||
(58, 'Mertens', 'Déborah', 'Flying Acrobatics Trampoline Club', '2009-11-04', 'F', 119801, 1, 16, 2),
|
||||
(59, 'Salhi', 'Safwane', 'Flying Acrobatics Trampoline Club', '2001-05-30', 'M', 4283, 1, 30, 7),
|
||||
(60, 'Pesesse', 'Lucas', 'Flying Acrobatics Trampoline Club', '2007-07-19', 'M', 70414, 1, 32, 4),
|
||||
(61, 'Carlini', 'Gabriel', 'Flying Acrobatics Trampoline Club', '2006-08-11', 'M', 103673, 1, 22, 5),
|
||||
(62, 'Demacker', 'Naomy', 'CGOM ASBL', '2004-04-14', 'F', 123439, 1, 10, 11),
|
||||
(63, 'Damri', 'Neila', 'TRAMPO NAMUR CLUB', '2004-06-14', 'F', 25026, 1, 62, 11),
|
||||
(64, 'Granda Martinez', 'Noelia', 'Flying Acrobatics Trampoline Club', '2003-01-28', 'F', 66196, 1, 52, 12),
|
||||
(65, 'Vanholder', 'Noah', 'Flying Acrobatics Trampoline Club', '2003-05-21', 'M', 101994, 1, 7, 12),
|
||||
(66, 'Pirson', 'Maxime', 'TRAMPO NAMUR CLUB', '2000-11-08', 'M', 24332, 1, 19, 13);
|
||||
|
||||
--
|
||||
-- Index pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Index pour la table `person_gymnast`
|
||||
--
|
||||
ALTER TABLE `person_gymnast`
|
||||
ADD PRIMARY KEY (`id`),
|
||||
ADD KEY `person_gymnast_category_id_f8d57860_fk_technic_a` (`category_id`);
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- AUTO_INCREMENT pour la table `person_gymnast`
|
||||
--
|
||||
ALTER TABLE `person_gymnast`
|
||||
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=67;
|
||||
--
|
||||
-- Contraintes pour les tables exportées
|
||||
--
|
||||
|
||||
--
|
||||
-- Contraintes pour la table `person_gymnast`
|
||||
--
|
||||
ALTER TABLE `person_gymnast`
|
||||
ADD CONSTRAINT `person_gymnast_category_id_f8d57860_fk_technic_a` FOREIGN KEY (`category_id`) REFERENCES `technic_availablecategory` (`id`);
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
|
@ -10,54 +10,51 @@ For the full list of settings and their values, see
|
|||
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
import environ
|
||||
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
from pathlib import Path
|
||||
|
||||
env = environ.Env(
|
||||
DEBUG=(bool, False)
|
||||
)
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
env = environ.Env(DEBUG=(bool, False))
|
||||
|
||||
environ.Env.read_env()
|
||||
|
||||
DEBUG = env('DEBUG', default=True)
|
||||
DEBUG = env("DEBUG", default=True)
|
||||
|
||||
SECRET_KEY = env('SECRET_KEY', default="6@9p0g-5ebcttbt$^*s4rda5!piezt6b7wj35g(+$mgz52k#d=")
|
||||
SECRET_KEY = env(
|
||||
"SECRET_KEY", default="6@9p0g-5ebcttbt$^*s4rda5!piezt6b7wj35g(+$mgz52k#d="
|
||||
)
|
||||
|
||||
DATABASES = {
|
||||
'default': env.db('DATABASE_URL', default='sqlite:///db.sqlite3')
|
||||
}
|
||||
DATABASES = {"default": env.db("DATABASE_URL", default="sqlite:///db.sqlite3")}
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
|
||||
ALLOWED_HOSTS = ["*"]
|
||||
|
||||
|
||||
# Application definition
|
||||
INSTALLED_APPS = (
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.admin",
|
||||
# 'django.contrib.admindocs',
|
||||
"django.contrib.auth",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"django_extensions",
|
||||
"people",
|
||||
"location",
|
||||
"planning",
|
||||
"objective",
|
||||
"competition",
|
||||
"profile",
|
||||
"tools",
|
||||
"communication",
|
||||
"khana.people",
|
||||
"khana.location",
|
||||
"khana.planning",
|
||||
"khana.objective",
|
||||
"khana.competition",
|
||||
"khana.profile",
|
||||
"khana.tools",
|
||||
"khana.communication",
|
||||
"rest_framework",
|
||||
)
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
#'django.middleware.csrf.CsrfViewMiddleware',
|
||||
|
@ -66,7 +63,7 @@ MIDDLEWARE = [
|
|||
#'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "khana.urls"
|
||||
ROOT_URLCONF = "config.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
|
@ -107,19 +104,20 @@ LOGIN_URL = "/login/"
|
|||
|
||||
LOGOUT_URL = "/logout/"
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
||||
MEDIA_URL = "/media/" # https://media.khana.be
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||
|
||||
STATIC_URL = "/static/"
|
||||
|
||||
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
|
||||
|
||||
MEDIA_URL = "/media/" # https://media.khana.be
|
||||
STATIC_ROOT = BASE_DIR / 'staticfiles'
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
|
||||
|
||||
DEBUG_TOOLBAR_CONFIG = {
|
||||
"JQUERY_URL": STATIC_URL + "js/jquery-2.1.4.min.js",
|
||||
}
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
|
|
@ -17,21 +17,22 @@ Including another URLconf
|
|||
from django.urls import include, path
|
||||
from django.conf.urls.static import static
|
||||
from django.contrib import admin
|
||||
from khana import settings
|
||||
|
||||
import khana.views
|
||||
import planning.views
|
||||
import people.views
|
||||
import objective.views
|
||||
import location.views
|
||||
from config import settings
|
||||
|
||||
import location.urls
|
||||
import people.urls
|
||||
import objective.urls
|
||||
import planning.urls
|
||||
import competition.urls
|
||||
import profile.urls
|
||||
import communication.urls
|
||||
import config.views
|
||||
import khana.planning.views
|
||||
import khana.people.views
|
||||
import khana.objective.views
|
||||
import khana.location.views
|
||||
|
||||
import khana.location.urls
|
||||
import khana.people.urls
|
||||
import khana.objective.urls
|
||||
import khana.planning.urls
|
||||
import khana.competition.urls
|
||||
import khana.profile.urls
|
||||
import khana.communication.urls
|
||||
|
||||
# import planningline_urlpatterns
|
||||
|
||||
|
@ -45,45 +46,45 @@ urlpatterns = [
|
|||
path(r"admin/", admin.site.urls),
|
||||
# url(r'^admin/jsi18n/$', include('django.views.i18n.javascript_catalog')), # pour le "ModelMultipleChoiceField" de event.forms
|
||||
# Profile list
|
||||
path(r"profile/", include(profile.urls.profile_urlpatterns)),
|
||||
path(r"profile/", include(khana.profile.urls.profile_urlpatterns)),
|
||||
# Attendance list
|
||||
path(r"attendance/", include(planning.urls.attendance_urlpatterns)),
|
||||
path(r"attendance/", include(khana.planning.urls.attendance_urlpatterns)),
|
||||
# About competition
|
||||
path(r"score/", include(competition.urls.score_urlpatterns)),
|
||||
path(r"score/", include(khana.competition.urls.score_urlpatterns)),
|
||||
# About gymnast
|
||||
path(r"gymnast/", include(people.urls.people_urlpatterns)),
|
||||
path(r"gymnast/", include(khana.people.urls.people_urlpatterns)),
|
||||
# About event
|
||||
path(r"event/", include(planning.urls.event_urlpatterns)),
|
||||
path(r"event/", include(khana.planning.urls.event_urlpatterns)),
|
||||
# About skill
|
||||
path(r"skill/", include(objective.urls.skill_urlpatterns)),
|
||||
path(r"skill/", include(khana.objective.urls.skill_urlpatterns)),
|
||||
# About chrono
|
||||
path(r"chrono/", include(objective.urls.chrono_urlpatterns)),
|
||||
path(r"chrono/", include(khana.objective.urls.chrono_urlpatterns)),
|
||||
# About skill
|
||||
path(r"training/", include(planning.urls.training_urlpatterns)),
|
||||
path(r"training/", include(khana.planning.urls.training_urlpatterns)),
|
||||
# About routine
|
||||
path(r"routine/", include(objective.urls.routine_urlpatterns)),
|
||||
path(r"routine/", include(khana.objective.urls.routine_urlpatterns)),
|
||||
# About accident
|
||||
path(r"accident/", include(people.urls.accident_urlpatterns)),
|
||||
path(r"accident/", include(khana.people.urls.accident_urlpatterns)),
|
||||
# About unavailability
|
||||
path(r"unavailability/", include(planning.urls.unavailability_urlpatterns)),
|
||||
path(r"unavailability/", include(khana.planning.urls.unavailability_urlpatterns)),
|
||||
# About planningline
|
||||
path(r"program/", include(planning.urls.planningline_urlpatterns)),
|
||||
path(r"program/", include(khana.planning.urls.planningline_urlpatterns)),
|
||||
# About course
|
||||
path(r"course/", include(planning.urls.course_urlpatterns)),
|
||||
path(r"messages/", include(communication.urls.message_urlpatterns)),
|
||||
path(r"course/", include(khana.planning.urls.course_urlpatterns)),
|
||||
path(r"messages/", include(khana.communication.urls.message_urlpatterns)),
|
||||
# About Location
|
||||
path(r"place/", include(location.urls.place_urlpatterns)),
|
||||
path(r"country/", include(location.urls.country_urlpatterns)),
|
||||
path(r"club/", include(location.urls.club_urlpatterns)),
|
||||
path(r"place/", include(khana.location.urls.place_urlpatterns)),
|
||||
path(r"country/", include(khana.location.urls.country_urlpatterns)),
|
||||
path(r"club/", include(khana.location.urls.club_urlpatterns)),
|
||||
# url(r'^club/', location.views.chooseStatistics),
|
||||
# url(r'^club/(?P<clubid>[0-9]+)', location.views.club_statistics),
|
||||
# Global search
|
||||
path(r"search/", khana.views.search, name="global_search"),
|
||||
path(r"search/", config.views.search, name="global_search"),
|
||||
# login & logout
|
||||
path(r"login/", khana.views.login, name="login"),
|
||||
path(r"logout/", khana.views.logout, name="logout"),
|
||||
path(r"login/", config.views.login, name="login"),
|
||||
path(r"logout/", config.views.logout, name="logout"),
|
||||
# Home page
|
||||
path(r"", khana.views.home, name="home"),
|
||||
path(r"", config.views.home, name="home"),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
# if settings.DEBUG:
|
|
@ -1,4 +1,8 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from datetime import datetime, timedelta, date
|
||||
from functools import reduce
|
||||
import operator
|
||||
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import render
|
||||
from django.template import RequestContext
|
||||
|
@ -9,23 +13,20 @@ from django.http import HttpResponseRedirect
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from datetime import datetime, timedelta, date
|
||||
from functools import reduce
|
||||
import operator
|
||||
import pendulum
|
||||
|
||||
from planning.models import (
|
||||
from khana.planning.models import (
|
||||
Season,
|
||||
Event,
|
||||
Unavailability,
|
||||
Course,
|
||||
get_number_of_weeks_between,
|
||||
)
|
||||
from people.models import Gymnast, Accident # people model
|
||||
from location.models import Club # location model
|
||||
from objective.models import Skill, Routine # objective model
|
||||
from profile.models import Profile
|
||||
from communication.views import get_number_of_unread_message
|
||||
import pendulum
|
||||
from khana.people.models import Gymnast, Accident # people model
|
||||
from khana.location.models import Club # location model
|
||||
from khana.objective.models import Skill, Routine # objective model
|
||||
from khana.profile.models import Profile
|
||||
from khana.communication.views import get_number_of_unread_message
|
||||
|
||||
|
||||
def login(request):
|
||||
|
@ -49,7 +50,7 @@ def login(request):
|
|||
request.session["template"] = profile.template_color
|
||||
request.session["sidebar"] = profile.sidebar_color
|
||||
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
||||
except expression as identifier:
|
||||
except Exception:
|
||||
pass
|
||||
request.session["clubid"] = request.POST.get("clubid", None)
|
||||
return HttpResponseRedirect("/")
|
||||
|
@ -81,8 +82,23 @@ def __getEventInfo(request):
|
|||
.. todo:: il refuse mon 'filter' que ce soit avant ou après le 'next(5)'. Une idée ?
|
||||
next_event = Event.objects.filter(club__in=(request.session["clubid"], )).next(5)
|
||||
"""
|
||||
|
||||
# rest = 0
|
||||
# counted = 0
|
||||
# event_list = []
|
||||
# today = pendulum.now().date()
|
||||
next_event_list = Event.objects.next(5)
|
||||
|
||||
# for event in next_event:
|
||||
# counted = event.get_number_of_occurence_to_event(today)
|
||||
# # print('pouf !')
|
||||
|
||||
# unavailabilities = Unavailability.objects.filter(datebegin__lte=event.datebegin.date(), dateend__gte=today)
|
||||
# for unavailable in unavailabilities:
|
||||
# counted -= unavailable.get_total_occurence()
|
||||
|
||||
# event_list.append((event, counted, int((counted/16)*100)))
|
||||
|
||||
return next_event_list
|
||||
|
||||
|
||||
|
@ -115,9 +131,18 @@ def __getCourseInfo(request):
|
|||
else:
|
||||
rest = int((tmp.days + 1) / 7)
|
||||
|
||||
# # select tous les unavailables liés au cours
|
||||
# unavailabilities = Unavailability.objects.filter(course=course)
|
||||
# for unavailable in unavailabilities:
|
||||
# tmp = unavailable.get_total_occurence()
|
||||
# counted -= tmp
|
||||
# rest -= tmp # si un unavailability.date < today, on soustrait quand même de rest ??? Si oui => BUG !!!!
|
||||
|
||||
courses_left += rest
|
||||
courses_done += counted - rest
|
||||
|
||||
# courses.append((course, counted, (counted - rest)))
|
||||
|
||||
return courses, courses_done, courses_left
|
||||
|
||||
|
||||
|
@ -135,10 +160,10 @@ def home(request):
|
|||
try:
|
||||
season = Season.objects.get(datebegin__lte=today, dateend__gte=today)
|
||||
except Season.DoesNotExist:
|
||||
context = {"error": "No season founded."}
|
||||
context = {"error": "No season found."}
|
||||
return render(request, "index.html", context)
|
||||
except Season.MultipleObjectsReturned:
|
||||
context = {"error": "Multiple season founded."}
|
||||
context = {"error": "Multiple season found."}
|
||||
return render(request, "index.html", context)
|
||||
|
||||
week_number = season.week_number_from_begin(today)
|
||||
|
@ -222,7 +247,8 @@ def search(request):
|
|||
name__icontains=pattern
|
||||
) # ou gymnaste qui y participe !
|
||||
gymnast_list = Gymnast.objects.filter(
|
||||
Q(user__last_name__icontains=pattern) | Q(user__first_name__icontains=pattern)
|
||||
Q(user__last_name__icontains=pattern)
|
||||
| Q(user__first_name__icontains=pattern)
|
||||
)
|
||||
accident_list = Accident.objects.filter(
|
||||
Q(gymnast__user__last_name__icontains=pattern)
|
|
@ -11,6 +11,6 @@ import os
|
|||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "khana.settings")
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
|
||||
|
||||
application = get_wsgi_application()
|
|
@ -9,6 +9,7 @@ from .models import Message
|
|||
class MessageAdmin(admin.ModelAdmin):
|
||||
"""La classe `MessageAdmin` contrôle la gestion des messages
|
||||
"""
|
||||
|
||||
list_display = ("sender", "recipient", "written_at", "is_read", "read_at")
|
||||
ordering = ("written_at", "sender")
|
||||
search_fields = ("sender", "recipient", "message_title")
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||
|
||||
|
||||
class CommunicationConfig(AppConfig):
|
||||
name = "communication"
|
||||
name = "khana.communication"
|
|
@ -8,6 +8,7 @@ from .models import Message
|
|||
class MessageForm(forms.ModelForm):
|
||||
"""Formulaire de base pour la création et la modification de messages
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = Message
|
||||
fields = (
|
|
@ -0,0 +1,63 @@
|
|||
# Generated by Django 3.2.2 on 2021-05-13 10:58
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
("communication", "0002_auto_20190413_1028"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="message", old_name="message_body", new_name="body",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="message", old_name="date_of_reading", new_name="read_at",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="message", old_name="message_title", new_name="title",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="message", old_name="date_of_writing", new_name="written_at",
|
||||
),
|
||||
migrations.RemoveField(model_name="message", name="is_read",),
|
||||
migrations.RemoveField(model_name="message", name="reader",),
|
||||
migrations.RemoveField(model_name="message", name="writer",),
|
||||
migrations.AddField(
|
||||
model_name="message",
|
||||
name="content",
|
||||
field=models.TextField(
|
||||
blank=True,
|
||||
help_text="Seul le MarkDown simple est accepté",
|
||||
null=True,
|
||||
verbose_name="Comments",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="message",
|
||||
name="recipient",
|
||||
field=models.ForeignKey(
|
||||
default=1,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="received_messages",
|
||||
to="auth.user",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="message",
|
||||
name="sender",
|
||||
field=models.ForeignKey(
|
||||
default=1,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="sent_messages",
|
||||
to="auth.user",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -12,7 +12,7 @@ from datetime import datetime
|
|||
from django.db import models
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from base.models import Markdownizable
|
||||
from khana.base.models import Markdownizable
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
|
@ -33,13 +33,11 @@ class Message(Markdownizable):
|
|||
sender = models.ForeignKey(
|
||||
User, on_delete=models.CASCADE, related_name="sent_messages"
|
||||
)
|
||||
written_at = models.DateTimeField(
|
||||
auto_now_add=True, verbose_name="Date of writing"
|
||||
)
|
||||
recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name="received_messages")
|
||||
read_at = models.DateTimeField(
|
||||
auto_now=True, verbose_name="Date of reading"
|
||||
written_at = models.DateTimeField(auto_now_add=True, verbose_name="Date of writing")
|
||||
recipient = models.ForeignKey(
|
||||
User, on_delete=models.CASCADE, related_name="received_messages"
|
||||
)
|
||||
read_at = models.DateTimeField(auto_now=True, verbose_name="Date of reading")
|
||||
title = models.CharField(max_length=255, verbose_name="Title")
|
||||
body = models.TextField(null=True, blank=True, verbose_name="Message")
|
||||
|
|
@ -14,6 +14,6 @@ def test_message_to_string():
|
|||
"""Vérifie la représentation textuelle d'un message
|
||||
"""
|
||||
timing = datetime.now()
|
||||
user = User(username='fred', password='fredpassword')
|
||||
user = User(username="fred", password="fredpassword")
|
||||
message = Message(sender=user, written_at=timing, title="test")
|
||||
assert str(message) == "fred - " + str(timing) + " : test"
|
|
@ -0,0 +1,92 @@
|
|||
"""Vues et fonctions pour tout ce qui touche à la communication entre plusieurs utilisateurs."""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.urls import reverse
|
||||
|
||||
from .forms import MessageForm
|
||||
from .models import Message
|
||||
|
||||
|
||||
@login_required
|
||||
def get_number_of_unread_message(request):
|
||||
"""Récupère le nombre de messages non lus associés à l'utilisateur en session.
|
||||
"""
|
||||
return (
|
||||
Message.objects.filter(recipient=request.user)
|
||||
.filter(read_at__isnull=True)
|
||||
.count()
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def get_received_messages(request):
|
||||
"""Récupère des messages recus pour l'utilisateur connecté.
|
||||
"""
|
||||
return request.user.received_messages.all()
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def get_sent_messages(request):
|
||||
"""Récupère des messages envoyés par l'utilisateur connecté.
|
||||
"""
|
||||
return request.user.sent_messages.all()
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def get_message_details(request, messageid):
|
||||
"""Récupère les détails (l'affichage ?) d'un message.
|
||||
"""
|
||||
message = get_object_or_404(Message, pk=messageid)
|
||||
if not message.read_at and message.recipient == request.user.id:
|
||||
message.read_at = datetime.now()
|
||||
message.save()
|
||||
|
||||
context = {"message": message, "type": None}
|
||||
return render(request, "message_details.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def delete_message(request, messageid):
|
||||
"""Supprime le message dont la clé est passée en paramètre.
|
||||
"""
|
||||
try:
|
||||
message = Message.objects.get(pk=messageid)
|
||||
|
||||
if message.sender == request.user or message.recipient == request.user:
|
||||
message.delete()
|
||||
else:
|
||||
return HttpResponse(401)
|
||||
except:
|
||||
return HttpResponse(400)
|
||||
|
||||
return HttpResponse(200)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def compose_message(request):
|
||||
"""Permet à l'utilisateur connecté de rédiger un nouveau message.
|
||||
"""
|
||||
|
||||
if request.method == "POST":
|
||||
form = MessageForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect(reverse("sent_messages"))
|
||||
|
||||
print("Invalid form")
|
||||
else:
|
||||
form = MessageForm()
|
||||
|
||||
context = {"form": form, "writer": request.user.id}
|
||||
return render(request, "message_create.html", context)
|
|
@ -15,7 +15,6 @@ class PointAdmin(admin.ModelAdmin):
|
|||
"total",
|
||||
)
|
||||
ordering = ("gymnast",)
|
||||
# search_fields = ('longLabel', 'shortLabel')
|
||||
list_filter = ("gymnast", "event", "routine_type")
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class CompetitionConfig(AppConfig):
|
||||
name = "khana.competition"
|
|
@ -1,4 +1,3 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
@ -14,7 +13,6 @@ class Point(models.Model):
|
|||
"people.Gymnast", on_delete=models.CASCADE, default=None
|
||||
)
|
||||
event = models.ForeignKey("planning.Event", on_delete=models.CASCADE, default=None)
|
||||
# routine=models.ForeignKey('objective.Routine')
|
||||
routine_type = models.PositiveSmallIntegerField(choices=ROUTINETYPE_CHOICE)
|
||||
point_execution = models.DecimalField(max_digits=5, decimal_places=3)
|
||||
point_difficulty = models.DecimalField(max_digits=3, decimal_places=1)
|
||||
|
@ -24,9 +22,8 @@ class Point(models.Model):
|
|||
total = models.DecimalField(max_digits=6, decimal_places=3)
|
||||
|
||||
def __str__(self):
|
||||
return "%s, %s - %s" % (
|
||||
self.gymnast.lastname,
|
||||
self.gymnast.firstname,
|
||||
return "%s - %s" % (
|
||||
self.gymnast,
|
||||
self.total,
|
||||
)
|
||||
|
|
@ -1,12 +1,7 @@
|
|||
# coding=UTF-8
|
||||
|
||||
import pytest
|
||||
from .models import (
|
||||
Point,
|
||||
Competition,
|
||||
Division,
|
||||
Level
|
||||
)
|
||||
from .models import Point, Competition, Division, Level
|
||||
|
||||
|
||||
# class TestModelCompetition(TestCase):
|
||||
|
@ -14,6 +9,7 @@ from .models import (
|
|||
# Tests relatifs à la classe `Compétition`.
|
||||
# """
|
||||
|
||||
|
||||
def test_competition_str_():
|
||||
""" Vérifie la représentation textuelle de la classe. """
|
||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
||||
|
@ -25,6 +21,7 @@ def test_competition_str_():
|
|||
# Tests relatifs à la classe `Division`.
|
||||
# """
|
||||
|
||||
|
||||
def test_division_str_():
|
||||
""" Vérifie la représentation textuelle de la classe. """
|
||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
||||
|
@ -37,6 +34,7 @@ def test_division_str_():
|
|||
# Tests relatifs à la classe `Level`.
|
||||
# """
|
||||
|
||||
|
||||
def test_level_str_():
|
||||
""" Vérifie la représentation textuelle de la classe. """
|
||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
|
@ -1,4 +1,3 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
@ -6,9 +5,10 @@ from django.http import HttpResponse, HttpResponseRedirect
|
|||
from django.views.decorators.http import require_http_methods
|
||||
from django.db.models import Q
|
||||
|
||||
from khana.people.models import Gymnast
|
||||
|
||||
from .forms import ScoreForm
|
||||
from .models import Point
|
||||
from people.models import Gymnast
|
||||
|
||||
|
||||
@login_required
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class LocationConfig(AppConfig):
|
||||
name = "khana.location"
|
|
@ -0,0 +1,75 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Country(models.Model):
|
||||
"""Classe représentant les pays (basée sur la liste ISO 3166 de 2015).
|
||||
|
||||
References:
|
||||
https://fr.wikipedia.org/wiki/ISO_3166
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Country"
|
||||
verbose_name_plural = "Countries"
|
||||
|
||||
nameus = models.CharField(max_length=255, verbose_name="English name")
|
||||
namefr = models.CharField(max_length=255, verbose_name="French Name")
|
||||
nationality = models.CharField(max_length=255, verbose_name="Nationality")
|
||||
iso2 = models.CharField(max_length=2)
|
||||
iso3 = models.CharField(max_length=3)
|
||||
isonum = models.PositiveSmallIntegerField()
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.namefr, self.iso2)
|
||||
|
||||
|
||||
class Place(models.Model):
|
||||
"""
|
||||
Représente un lieu. En plus de l'adresse, un lieu est spécifié par un nombre
|
||||
de kilomètres et une durée de trajet. Pour faciliter les filtres, un lieu peut être
|
||||
actif ou non.
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Place"
|
||||
verbose_name_plural = "Places"
|
||||
|
||||
name = models.CharField(max_length=255, verbose_name="Name")
|
||||
address = models.CharField(max_length=255, verbose_name="Address")
|
||||
postal = models.PositiveIntegerField(verbose_name="Postal code")
|
||||
city = models.CharField(max_length=255, verbose_name="City")
|
||||
country = models.ForeignKey(
|
||||
Country, verbose_name="Country", on_delete=models.CASCADE, default=None
|
||||
)
|
||||
nbkm = models.PositiveIntegerField(blank=True, null=True, help_text="in km")
|
||||
timing = models.PositiveIntegerField(blank=True, null=True, help_text="in minutes")
|
||||
active = models.BooleanField(default=1, verbose_name="Active")
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.name, self.city if self.city else "?")
|
||||
|
||||
|
||||
class Club(models.Model):
|
||||
"""
|
||||
Représente un club. Un club est associé à un lieu. Pour faciliter les filtres,
|
||||
un club peut être actif ou non.
|
||||
|
||||
.. todo:: Un club peut avoir plusieurs salle et une salle peut-être louée par plusieurs clubs... M2M ?
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Club"
|
||||
verbose_name_plural = "Clubs"
|
||||
|
||||
# place=models.ManyToManyField(Place, through="clubs")
|
||||
place = models.ForeignKey(
|
||||
Place, verbose_name="Place", on_delete=models.CASCADE, default=None
|
||||
)
|
||||
name = models.CharField(max_length=255, verbose_name="Name")
|
||||
acronym = models.CharField(max_length=4, verbose_name="Acronym")
|
||||
active = models.BooleanField(default=1, verbose_name="Active")
|
||||
|
||||
def __str__(self):
|
||||
return "%s (à %s)" % (self.name, self.place.city if self.place.city else "?")
|
|
@ -8,10 +8,7 @@ from ..models import Club, Country, Place
|
|||
class TestCountry(TestCase):
|
||||
def test_str_should_contain_name_and_iso2(self):
|
||||
country = Country.objects.create(
|
||||
nameus="Belgium",
|
||||
namefr="Belgique",
|
||||
isonum=56,
|
||||
iso2="BE"
|
||||
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||
)
|
||||
|
||||
self.assertEqual(str(country), "Belgique (BE)")
|
||||
|
@ -23,11 +20,8 @@ class TestPlace(TestCase):
|
|||
name="Heaven",
|
||||
postal=1080,
|
||||
country=Country.objects.create(
|
||||
nameus="Belgium",
|
||||
namefr="Belgique",
|
||||
isonum=56,
|
||||
iso2="BE"
|
||||
)
|
||||
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||
),
|
||||
)
|
||||
|
||||
self.assertEqual(str(place), "Heaven (?)")
|
||||
|
@ -41,12 +35,9 @@ class TestClub(TestCase):
|
|||
name="Heaven",
|
||||
postal=1080,
|
||||
country=Country.objects.create(
|
||||
nameus="Belgium",
|
||||
namefr="Belgique",
|
||||
isonum=56,
|
||||
iso2="BE"
|
||||
)
|
||||
)
|
||||
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
self.assertEqual(str(club), "RSCA (à ?)")
|
|
@ -0,0 +1,20 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from .models import Club, Place, Country
|
||||
import pytest
|
||||
|
||||
# class GymnastTestCase():
|
||||
def test_country_tostring():
|
||||
c = Country(namefr="Belgique", iso2="56")
|
||||
assert str(c) == "Belgique (56)"
|
||||
|
||||
|
||||
def test_place_tostring():
|
||||
p = Place(name="FATC", city="Lillois")
|
||||
assert str(p) == "FATC (Lillois)"
|
||||
|
||||
|
||||
def test_club_tostring():
|
||||
p = Place(name="FATC", city="Lillois")
|
||||
club = Club(place=p, name="FATC2")
|
||||
assert str(club) == "FATC2 (à Lillois)"
|
|
@ -1,35 +1,45 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.db.models import Q, Count
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.utils.html import format_html
|
||||
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from datetime import datetime, timedelta, date
|
||||
from functools import reduce
|
||||
import operator
|
||||
import simplejson
|
||||
|
||||
from planning.models import (
|
||||
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db.models import Q, Count
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.utils.html import format_html
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from khana.planning.models import (
|
||||
Event,
|
||||
Unavailability,
|
||||
Course,
|
||||
Subgroup,
|
||||
Training,
|
||||
) # planning model
|
||||
from people.models import Gymnast, Accident # people model
|
||||
)
|
||||
from khana.objective.models import Skill, Routine
|
||||
from khana.people.models import Gymnast, Accident
|
||||
|
||||
from .models import (
|
||||
Club,
|
||||
Country,
|
||||
GymnastStatistics,
|
||||
Place,
|
||||
Country,
|
||||
)
|
||||
from .forms import PlaceForm
|
||||
from objective.models import Skill, Routine # objective model
|
||||
|
||||
|
||||
def __diffTime(end, start):
|
||||
"""
|
||||
Prend deux `datetime.time` en paramètre et calcul la différence entre les deux.
|
||||
"""
|
||||
startdate = datetime(2000, 1, 1, start.hour, start.minute)
|
||||
enddate = datetime(2000, 1, 1, end.hour, end.minute)
|
||||
|
||||
return enddate - startdate
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -78,7 +88,7 @@ def place_listing(request):
|
|||
"""
|
||||
place_list = Place.objects.all()
|
||||
context = {"place_list": place_list}
|
||||
return render(request, "place_list.html", context)
|
||||
return render(request, "places/list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -106,7 +116,7 @@ def place_create_or_update(request, placeid=None):
|
|||
form = PlaceForm(instance=place, initial=data)
|
||||
|
||||
context = {"form": form, "placeid": placeid}
|
||||
return render(request, "place_create.html", context)
|
||||
return render(request, "places/create.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -117,7 +127,7 @@ def place_details(request, placeid):
|
|||
"""
|
||||
place = get_object_or_404(Place, pk=placeid)
|
||||
context = {"place": place}
|
||||
return render(request, "place_details.html", context)
|
||||
return render(request, "places/details.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
@ -144,133 +154,11 @@ def chooseStatistics(request):
|
|||
return render(request, "club_statistics.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
def club_statistics_new(request, clubid):
|
||||
"""Construit les statistiques d'un club, pour une saison choisie
|
||||
|
||||
Questions:
|
||||
Tu dis que cela construit les stats d'un club __pour une saison__...
|
||||
Mais je ne vois pas la saison dans les paramètres...
|
||||
|
||||
Todo:
|
||||
* Tenir compte de la saison.
|
||||
"""
|
||||
club = Club.objects.get(pk=clubid)
|
||||
courses = Course.objects.filter(club__in=clubid).order_by(
|
||||
"iso_day_number", "hour_begin"
|
||||
)
|
||||
|
||||
total_hours = 0
|
||||
totalHoursByWeek = 0
|
||||
totalHoursPaid = 0
|
||||
gymnastsDict = {}
|
||||
gymnasts = []
|
||||
courseList = []
|
||||
|
||||
for course in courses:
|
||||
list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
|
||||
gymnasts.extend(list_of_gymnasts)
|
||||
number_of_gymnasts = len(list_of_gymnasts)
|
||||
|
||||
number_of_course_hours = course.number_of_hours
|
||||
totalHoursByWeek += number_of_course_hours.seconds
|
||||
|
||||
counted = course.get_number_of_real_occurrences
|
||||
|
||||
totalTimeForCourse = number_of_course_hours * counted # timedelta
|
||||
totalHourForCourse = (totalTimeForCourse.days * 24) + (
|
||||
totalTimeForCourse.seconds / 3600
|
||||
)
|
||||
totalHours += totalHourForCourse
|
||||
totalHoursPaidForCourse = totalHourForCourse * course.number_of_trainers
|
||||
totalHoursPaid += totalHoursPaidForCourse
|
||||
|
||||
hour = number_of_course_hours.seconds / 3600
|
||||
|
||||
courseList.append(
|
||||
(
|
||||
course,
|
||||
course.number_of_trainers,
|
||||
number_of_gymnasts,
|
||||
hour,
|
||||
course.get_number_of_real_occurrences,
|
||||
totalHourForCourse,
|
||||
totalHoursPaidForCourse,
|
||||
)
|
||||
)
|
||||
|
||||
for gymnast in list_of_gymnasts:
|
||||
|
||||
gymnast_stats = gymnastsDict.setdefault(gymnast.id, GymnastStatistics(gymnast))
|
||||
|
||||
attendance_list = Training.objects.filter(course=course, gymnast=gymnast)
|
||||
number_of_attendance = attendance_list.count()
|
||||
|
||||
gymnast_stats.number_of_courses_by_week += 1
|
||||
gymnast_stats.number_of_hours_by_week += nbhour
|
||||
gymnast_stats.number_of_trainings += counted
|
||||
gymnast_stats.number_of_attendance += number_of_attendance
|
||||
gymnast_stats.number_of_training_hours += totalHourForCourse
|
||||
gymnast_stats.number_of_attendance_hours += (
|
||||
nbhour * number_of_attendance
|
||||
)
|
||||
|
||||
# tous les cours ont été traités
|
||||
totalHoursByWeek = totalHoursByWeek / 3600
|
||||
|
||||
gymnasts = set(gymnasts)
|
||||
|
||||
for gymnast in gymnasts:
|
||||
tmp = int(gymnastsDict[gymnast.id]["nbhourbyweek"].seconds / 3600)
|
||||
gymnastsDict[gymnast.id]["nbhourbyweek"] = "%d:%02d" % (
|
||||
tmp,
|
||||
(gymnastsDict[gymnast.id]["nbhourbyweek"].seconds - (tmp * 3600)) / 60,
|
||||
)
|
||||
|
||||
gymnastsDict[gymnast.id]["nbabsence"] = (
|
||||
gymnastsDict[gymnast.id]["nbtraining"]
|
||||
- gymnastsDict[gymnast.id]["nbattendance"]
|
||||
)
|
||||
|
||||
# tmp = (gymnastsDict[gymnast.id]['nbhourattendance'].days * 24) + (gymnastsDict[gymnast.id]['nbhourattendance'].seconds/3600)
|
||||
gymnastsDict[gymnast.id]["nbhourattendance"] = (
|
||||
gymnastsDict[gymnast.id]["nbhourattendance"].days * 24
|
||||
) + (gymnastsDict[gymnast.id]["nbhourattendance"].seconds / 3600)
|
||||
|
||||
gymnastsDict[gymnast.id]["nbhourabsence"] = (
|
||||
gymnastsDict[gymnast.id]["nbhourtraining"]
|
||||
- gymnastsDict[gymnast.id]["nbhourattendance"]
|
||||
)
|
||||
|
||||
gymnastsDict[gymnast.id]["percentageattendance"] = int(
|
||||
(
|
||||
gymnastsDict[gymnast.id]["nbhourattendance"]
|
||||
/ gymnastsDict[gymnast.id]["nbhourtraining"]
|
||||
)
|
||||
* 100
|
||||
)
|
||||
gymnastsDict[gymnast.id]["percentageabsence"] = int(
|
||||
(
|
||||
gymnastsDict[gymnast.id]["nbhourabsence"]
|
||||
/ gymnastsDict[gymnast.id]["nbhourtraining"]
|
||||
)
|
||||
* 100
|
||||
)
|
||||
|
||||
context = {
|
||||
"courses": courseList,
|
||||
"gymnasts": gymnastsDict,
|
||||
"totalHoursByWeek": totalHoursByWeek,
|
||||
"totalCourses": club.get_number_of_real_occurrences,
|
||||
"totalHours": totalHours,
|
||||
"totalHoursPaid": totalHoursPaid,
|
||||
}
|
||||
return context
|
||||
|
||||
@login_required
|
||||
def club_statistics(request, clubid):
|
||||
"""
|
||||
Renvoie les statistiques d'un club pour une saison choisie.
|
||||
|
||||
.. todo:: tenir compte de la saison.
|
||||
"""
|
||||
|
||||
|
@ -285,9 +173,8 @@ def club_statistics(request, clubid):
|
|||
gymnastsDict = {}
|
||||
gymnasts = []
|
||||
courseList = []
|
||||
|
||||
for course in courses:
|
||||
|
||||
nbtrainer = course.trainers.count()
|
||||
list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
|
||||
gymnasts.extend(list_of_gymnasts)
|
||||
nbgymnast = len(list_of_gymnasts)
|
||||
|
@ -296,8 +183,38 @@ def club_statistics(request, clubid):
|
|||
nbhour = __diffTime(course.hour_end, course.hour_begin) # timedelta
|
||||
totalHoursByWeek += nbhour.seconds
|
||||
|
||||
counted = course.get_total_occurence()
|
||||
|
||||
# select tous les unavailables liés au cours
|
||||
unavailabilities = Unavailability.objects.filter(course=course)
|
||||
for unavailable in unavailabilities:
|
||||
counted -= unavailable.get_total_occurence()
|
||||
|
||||
totalCourses += counted
|
||||
totalTimeForCourse = nbhour * counted # timedelta
|
||||
totalHourForCourse = (totalTimeForCourse.days * 24) + (
|
||||
totalTimeForCourse.seconds / 3600
|
||||
)
|
||||
totalHours += totalHourForCourse
|
||||
totalHoursPaidForCourse = totalHourForCourse * nbtrainer
|
||||
totalHoursPaid += totalHoursPaidForCourse
|
||||
|
||||
# tmp = int(nbhour.seconds/3600)
|
||||
# hour = "%d:%02d" % (tmp, (nbhour.seconds - (tmp * 3600)) / 60)
|
||||
hour = nbhour.seconds / 3600
|
||||
|
||||
courseList.append(
|
||||
(
|
||||
course,
|
||||
nbtrainer,
|
||||
nbgymnast,
|
||||
hour,
|
||||
counted,
|
||||
totalHourForCourse,
|
||||
totalHoursPaidForCourse,
|
||||
)
|
||||
)
|
||||
|
||||
for gymnast in list_of_gymnasts:
|
||||
# print(gymnast)
|
||||
if gymnast.id not in gymnastsDict:
|
||||
|
@ -320,10 +237,14 @@ def club_statistics(request, clubid):
|
|||
|
||||
# print(str(gymnast) + ' : ' + str(nbattendance) + ' for ' + str(course) )
|
||||
|
||||
gymnastsDict[gymnast.id]["nbcoursebyweek"] += 1
|
||||
gymnastsDict[gymnast.id]["nbhourbyweek"] += nbhour # timedelta
|
||||
gymnastsDict[gymnast.id]["nbtraining"] += counted
|
||||
gymnastsDict[gymnast.id]["nbattendance"] += nbattendance
|
||||
gymnastsDict[gymnast.id]["nbhourtraining"] += totalHourForCourse
|
||||
|
||||
gymnastsDict[gymnast.id]["nbhourattendance"] += (
|
||||
nbhour * nbattendance
|
||||
) # timedelta
|
||||
|
||||
# print(gymnastsDict[gymnast.id])
|
||||
|
||||
|
@ -379,4 +300,3 @@ def club_statistics(request, clubid):
|
|||
"totalHoursPaid": totalHoursPaid,
|
||||
}
|
||||
return context
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
import math
|
||||
|
||||
from people.models import Gymnast
|
||||
from objectives.models import Skill
|
||||
from khana.people.models import Gymnast
|
||||
from khana.objective.models import Skill
|
||||
|
||||
|
||||
def suggest_routine(
|
||||
|
@ -58,16 +59,17 @@ def suggest_routine(
|
|||
for skill in skill_list:
|
||||
current_routine.append(skill)
|
||||
current_routine.append(
|
||||
self.suggest_routine(
|
||||
request,
|
||||
total_difficulty_score - skill.difficulty,
|
||||
max_difficulty_score,
|
||||
routine_length - 1,
|
||||
competition,
|
||||
logic,
|
||||
gymnast,
|
||||
skill,
|
||||
)
|
||||
None
|
||||
# suggest_routine()
|
||||
# request,
|
||||
# total_difficulty_score - skill.difficulty,
|
||||
# max_difficulty_score,
|
||||
# routine_length - 1,
|
||||
# competition,
|
||||
# logic,
|
||||
# gymnast,
|
||||
# skill,
|
||||
# )
|
||||
)
|
||||
current_routine.pop()
|
||||
# def knapSack(W, wt, val, n):
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
from .models import (
|
||||
Educative,
|
||||
TouchPosition,
|
||||
|
@ -30,12 +30,8 @@ def duplicate_skill(self, SkillAdmin, request, queryset):
|
|||
class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
||||
model = Skill
|
||||
|
||||
# related_search_fields = {
|
||||
# 'departure': ('label', 'short_label'),
|
||||
# 'landing': ('label', 'short_label')
|
||||
# }
|
||||
fields = (
|
||||
"label",
|
||||
"long_label",
|
||||
"short_label",
|
||||
"information",
|
||||
"departure",
|
||||
|
@ -57,7 +53,7 @@ class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
|||
)
|
||||
|
||||
list_display = (
|
||||
"label",
|
||||
"long_label",
|
||||
"difficulty",
|
||||
"is_competitive",
|
||||
"level",
|
||||
|
@ -66,9 +62,9 @@ class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
|||
"age_boy",
|
||||
"age_girl",
|
||||
)
|
||||
# list_display = ('label', 'short_label', 'prerequisite')
|
||||
ordering = ("label", "short_label")
|
||||
search_fields = ("rank", "label", "short_label")
|
||||
|
||||
ordering = ("long_label", "short_label")
|
||||
search_fields = ("rank", "long_label", "short_label")
|
||||
list_filter = (
|
||||
"is_competitive",
|
||||
"departure",
|
||||
|
@ -94,7 +90,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
model = Routine
|
||||
|
||||
fields = (
|
||||
"label",
|
||||
"long_label",
|
||||
"short_label",
|
||||
"difficulty",
|
||||
"level",
|
||||
|
@ -107,7 +103,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
"is_competitive",
|
||||
)
|
||||
list_display = (
|
||||
"label",
|
||||
"long_label",
|
||||
"short_label",
|
||||
"is_competitive",
|
||||
"active",
|
||||
|
@ -117,7 +113,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
)
|
||||
list_filter = ("level", "difficulty", "is_competitive", "active")
|
||||
search_fields = (
|
||||
"label",
|
||||
"long_label",
|
||||
"short_label",
|
||||
)
|
||||
|
||||
|
@ -127,10 +123,10 @@ class RoutineAdmin(admin.ModelAdmin):
|
|||
js = ("js/routine.js",)
|
||||
|
||||
# TODO: ne proposer QUE les SKILL comme educatif
|
||||
def get_related_filter(self, model, request):
|
||||
# print('boum')
|
||||
if not issubclass(model, Educative):
|
||||
return super(Skill, self).get_related_filter(model, request)
|
||||
# def get_related_filter(self, model, request):
|
||||
# # print('boum')
|
||||
# if not issubclass(model, Educative):
|
||||
# return super(Skill, self).get_related_filter(model, request)
|
||||
|
||||
|
||||
class RoutineSkillAdmin(admin.ModelAdmin):
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ObjectiveConfig(AppConfig):
|
||||
name = "khana.objective"
|
|
@ -8,13 +8,13 @@ from .models import Routine, RoutineSkill, Chrono
|
|||
class RoutineForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Routine
|
||||
fields = ("label", "label", "difficulty", "level", "active")
|
||||
fields = ("long_label", "short_label", "difficulty", "level", "active")
|
||||
widgets = {
|
||||
# Champs obligatoires de la classe mère.
|
||||
"label": forms.TextInput(
|
||||
"long_label": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Routine's long name"}
|
||||
),
|
||||
"label": forms.TextInput(
|
||||
"short_label": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Routine's short name"}
|
||||
),
|
||||
"difficulty": forms.HiddenInput(),
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import objective.models
|
||||
import khana.objective.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -28,7 +28,7 @@ class Migration(migrations.Migration):
|
|||
model_name="skill",
|
||||
name="departure",
|
||||
field=models.ForeignKey(
|
||||
default=objective.models.get_default_position,
|
||||
default=khana.objective.models.get_default_position,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="depart_of",
|
||||
to="objective.TouchPosition",
|
||||
|
@ -39,7 +39,7 @@ class Migration(migrations.Migration):
|
|||
model_name="skill",
|
||||
name="landing",
|
||||
field=models.ForeignKey(
|
||||
default=objective.models.get_default_position,
|
||||
default=khana.objective.models.get_default_position,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="landing_of",
|
||||
to="objective.TouchPosition",
|
|
@ -6,13 +6,11 @@ from django.db import migrations
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('objective', '0015_auto_20190524_1211'),
|
||||
("objective", "0015_auto_20190524_1211"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='educative',
|
||||
old_name='information',
|
||||
new_name='content',
|
||||
model_name="educative", old_name="information", new_name="content",
|
||||
),
|
||||
]
|
|
@ -0,0 +1,75 @@
|
|||
# Generated by Django 3.2.2 on 2021-06-20 16:18
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("objective", "0016_rename_information_educative_content"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(old_name="Routine_Skill", new_name="RoutineSkill",),
|
||||
migrations.AlterModelOptions(
|
||||
name="educative",
|
||||
options={
|
||||
"ordering": ["label", "short_label"],
|
||||
"verbose_name": "Educatif",
|
||||
"verbose_name_plural": "Educatifs",
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name="touchposition",
|
||||
options={
|
||||
"ordering": [
|
||||
"label",
|
||||
"short_label",
|
||||
"is_default",
|
||||
"allowed_in_competition",
|
||||
],
|
||||
"verbose_name": "Landing",
|
||||
"verbose_name_plural": "Landings",
|
||||
},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="ageBoy", new_name="age_boy",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="ageGirl", new_name="age_girl",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="educative", new_name="educatives",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="longLabel", new_name="label",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="prerequisite", new_name="prerequisites",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="educative", old_name="shortLabel", new_name="short_label",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="skill", old_name="rotationType", new_name="rotation_type",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="skill",
|
||||
old_name="simplyNotation",
|
||||
new_name="simplified_notation",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="touchposition",
|
||||
old_name="competition",
|
||||
new_name="allowed_in_competition",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="touchposition", old_name="default", new_name="is_default",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="touchposition", old_name="longLabel", new_name="label",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="touchposition", old_name="shortLabel", new_name="short_label",
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 3.2.8 on 2021-12-05 11:33
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('objective', '0017_auto_20210620_1618'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='educative',
|
||||
options={'ordering': ['long_label', 'short_label'], 'verbose_name': 'Educatif', 'verbose_name_plural': 'Educatifs'},
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name='educative',
|
||||
old_name='label',
|
||||
new_name='long_label',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,53 @@
|
|||
# Generated by Django 4.0.1 on 2022-01-13 21:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('objective', '0018_auto_20211205_1133'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_boy_chained',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Boy's age chained"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_boy_masterised',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Boy's age masterised"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_boy_with_help',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Boy's age with help"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_boy_without_help',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Boy's age without help"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_girl_chained',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Girl's age chained"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_girl_masterised',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Girl's age masterised"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_girl_with_help',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Girl's age with help"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='educative',
|
||||
name='age_girl_without_help',
|
||||
field=models.PositiveSmallIntegerField(choices=[(6, '6-7'), (7, '7-8'), (8, '8-9'), (9, '9-10'), (10, '10-11'), (11, '11-12'), (12, '12-13'), (13, '13-14'), (14, '14-15'), (15, '15-16'), (16, '16-17'), (17, '17+')], default=6, verbose_name="Girl's age without help"),
|
||||
),
|
||||
]
|
|
@ -1,10 +1,13 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from datetime import date
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from base.models import Markdownizable
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from khana.base.models import Markdownizable
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Educative(Markdownizable):
|
||||
|
@ -12,35 +15,76 @@ class Educative(Markdownizable):
|
|||
Classe `mère`.
|
||||
"""
|
||||
|
||||
AGE_CHOICES = (
|
||||
(6, "6-7"),
|
||||
(7, "7-8"),
|
||||
(8, "8-9"),
|
||||
(9, "9-10"),
|
||||
(10, "10-11"),
|
||||
(11, "11-12"),
|
||||
(12, "12-13"),
|
||||
(13, "13-14"),
|
||||
(14, "14-15"),
|
||||
(15, "15-16"),
|
||||
(16, "16-17"),
|
||||
(17, "17+"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Educatif"
|
||||
verbose_name_plural = "Educatifs"
|
||||
ordering = ["label", "short_label"] # 'level',
|
||||
ordering = ["long_label", "short_label"] # 'level',
|
||||
|
||||
label = models.CharField(max_length = 255, verbose_name = "Long Name")
|
||||
short_label = models.CharField(max_length = 255, verbose_name = "Short Name")
|
||||
long_label = models.CharField(max_length=255, verbose_name="Long Name")
|
||||
short_label = models.CharField(max_length=255, verbose_name="Short Name")
|
||||
difficulty = models.DecimalField(
|
||||
max_digits = 3, decimal_places = 1, verbose_name = "Difficulty"
|
||||
max_digits=3, decimal_places=1, verbose_name="Difficulty"
|
||||
)
|
||||
level = models.PositiveSmallIntegerField(verbose_name = "Level", default = 0)
|
||||
rank = models.PositiveSmallIntegerField(verbose_name = "Rank", default = 0)
|
||||
level = models.PositiveSmallIntegerField(verbose_name="Level", default=0)
|
||||
rank = models.PositiveSmallIntegerField(verbose_name="Rank", default=0)
|
||||
educatives = models.ManyToManyField(
|
||||
"self", related_name = "educativeOf", blank = True, symmetrical = False
|
||||
"self", related_name="educativeOf", blank=True, symmetrical=False
|
||||
)
|
||||
prerequisites = models.ManyToManyField(
|
||||
"self", related_name = "prerequisiteOf", blank = True, symmetrical = False
|
||||
"self", related_name="prerequisiteOf", blank=True, symmetrical=False
|
||||
)
|
||||
age_boy = models.PositiveSmallIntegerField(
|
||||
blank = True, null = True, verbose_name = "Boy's age"
|
||||
blank=True, null=True, verbose_name="Boy's age"
|
||||
)
|
||||
age_girl = models.PositiveSmallIntegerField(
|
||||
blank = True, null = True, verbose_name = "Girl's age"
|
||||
blank=True, null=True, verbose_name="Girl's age"
|
||||
)
|
||||
|
||||
age_boy_with_help = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Boy's age with help", default=6
|
||||
)
|
||||
age_boy_without_help = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Boy's age without help", default=6
|
||||
)
|
||||
age_boy_chained = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Boy's age chained", default=6
|
||||
)
|
||||
age_boy_masterised = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Boy's age masterised", default=6
|
||||
)
|
||||
|
||||
age_girl_with_help = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Girl's age with help", default=6
|
||||
)
|
||||
age_girl_without_help = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Girl's age without help", default=6
|
||||
)
|
||||
age_girl_chained = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Girl's age chained", default=6
|
||||
)
|
||||
age_girl_masterised = models.PositiveSmallIntegerField(
|
||||
choices=AGE_CHOICES, verbose_name="Girl's age masterised", default=6
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "%s - %s (level: %s | diff: %s)" % (
|
||||
self.rank,
|
||||
self.longLabel,
|
||||
self.label,
|
||||
self.level,
|
||||
self.difficulty,
|
||||
)
|
||||
|
@ -56,13 +100,13 @@ class TouchPosition(models.Model):
|
|||
verbose_name_plural = "Landings"
|
||||
ordering = ["label", "short_label", "is_default", "allowed_in_competition"]
|
||||
|
||||
label = models.CharField(max_length = 30, verbose_name = "Nom long")
|
||||
short_label = models.CharField(max_length = 15, verbose_name = "Nom court")
|
||||
allowed_in_competition = models.BooleanField(verbose_name = "Compétition")
|
||||
is_default = models.BooleanField(verbose_name = "Défaut")
|
||||
label = models.CharField(max_length=30, verbose_name="Nom long")
|
||||
short_label = models.CharField(max_length=15, verbose_name="Nom court")
|
||||
allowed_in_competition = models.BooleanField(verbose_name="Compétition")
|
||||
is_default = models.BooleanField(verbose_name="Défaut")
|
||||
|
||||
def __str__(self):
|
||||
return "%s" % (self.longLabel)
|
||||
return "%s" % (self.label)
|
||||
|
||||
|
||||
def get_default_position():
|
||||
|
@ -104,29 +148,31 @@ class Skill(Educative):
|
|||
(2, "Backward"),
|
||||
)
|
||||
|
||||
position = models.CharField(max_length = 2, choices = POSITION_CHOICES)
|
||||
position = models.CharField(max_length=2, choices=POSITION_CHOICES)
|
||||
departure = models.ForeignKey(
|
||||
TouchPosition,
|
||||
related_name = "depart_of",
|
||||
default = get_default_position,
|
||||
verbose_name = "Take-off position",
|
||||
on_delete = models.CASCADE,
|
||||
related_name="depart_of",
|
||||
default=get_default_position,
|
||||
verbose_name="Take-off position",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
landing = models.ForeignKey(
|
||||
TouchPosition,
|
||||
related_name = "landing_of",
|
||||
default = get_default_position,
|
||||
verbose_name = "Landing position",
|
||||
on_delete = models.CASCADE,
|
||||
related_name="landing_of",
|
||||
default=get_default_position,
|
||||
verbose_name="Landing position",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
rotation_type = models.PositiveSmallIntegerField(
|
||||
choices = ROTATION_CHOICES, verbose_name = "Type de rotation"
|
||||
choices=ROTATION_CHOICES, verbose_name="Type de rotation"
|
||||
)
|
||||
rotation = models.PositiveSmallIntegerField(verbose_name = "1/4 de rotation")
|
||||
twist = models.PositiveSmallIntegerField(verbose_name = "1/2 Vrille")
|
||||
notation = models.CharField(max_length = 25)
|
||||
simplified_notation = models.CharField(max_length = 25, verbose_name = "Notation simplifiée")
|
||||
is_competitive = models.BooleanField(default = False)
|
||||
rotation = models.PositiveSmallIntegerField(verbose_name="1/4 de rotation")
|
||||
twist = models.PositiveSmallIntegerField(verbose_name="1/2 Vrille")
|
||||
notation = models.CharField(max_length=25)
|
||||
simplified_notation = models.CharField(
|
||||
max_length=25, verbose_name="Notation simplifiée"
|
||||
)
|
||||
is_competitive = models.BooleanField(default=False)
|
||||
# importance = models.PositiveSmallIntegerField(default = 1)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -144,12 +190,12 @@ class Routine(Educative):
|
|||
|
||||
active = models.BooleanField()
|
||||
jumps = models.ManyToManyField(
|
||||
Skill, through = "RoutineSkill", verbose_name = "routine"
|
||||
Skill, through="RoutineSkill", verbose_name="routine"
|
||||
) # ceci n'est pas un vrai champ
|
||||
is_competitive = models.BooleanField(default = False)
|
||||
is_competitive = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s)" % (self.label, self.short_label)
|
||||
return "%s (%s)" % (self.long_label, self.short_label)
|
||||
|
||||
def contains_basic_jumps(self):
|
||||
"""
|
||||
|
@ -216,10 +262,10 @@ class RoutineSkill(models.Model):
|
|||
ordering = ("rank",)
|
||||
|
||||
routine = models.ForeignKey(
|
||||
Routine, on_delete = models.CASCADE, default = None, related_name = "skill_links"
|
||||
Routine, on_delete=models.CASCADE, default=None, related_name="skill_links"
|
||||
)
|
||||
skill = models.ForeignKey(
|
||||
Skill, on_delete = models.CASCADE, default = None, related_name = "routine_links"
|
||||
Skill, on_delete=models.CASCADE, default=None, related_name="routine_links"
|
||||
)
|
||||
rank = models.PositiveSmallIntegerField()
|
||||
|
||||
|
@ -247,13 +293,13 @@ class Chrono(models.Model):
|
|||
(99, "Other"),
|
||||
)
|
||||
|
||||
routine = models.ForeignKey(Routine, on_delete = models.CASCADE, default = None)
|
||||
routine_type = models.PositiveSmallIntegerField(choices = ROUTINETYPE_CHOICE)
|
||||
routine = models.ForeignKey(Routine, on_delete=models.CASCADE, default=None)
|
||||
routine_type = models.PositiveSmallIntegerField(choices=ROUTINETYPE_CHOICE)
|
||||
gymnast = models.ForeignKey(
|
||||
"people.gymnast", on_delete = models.CASCADE, default = None
|
||||
"people.gymnast", on_delete=models.CASCADE, default=None
|
||||
)
|
||||
date = models.DateField(default = date.today, verbose_name = "Date")
|
||||
score = models.DecimalField(max_digits = 5, decimal_places = 2)
|
||||
date = models.DateField(default=date.today, verbose_name="Date")
|
||||
score = models.DecimalField(max_digits=5, decimal_places=2)
|
||||
|
||||
def __str__(self):
|
||||
return "%s le %s : %s pour %s" % (
|
||||
|
@ -278,13 +324,13 @@ class Evaluation(models.Model):
|
|||
Classe permettant l'évaluation des éducatifs.
|
||||
"""
|
||||
|
||||
date = models.DateField(default = date.today, verbose_name = "Date")
|
||||
value = models.PositiveSmallIntegerField(default = 0)
|
||||
date = models.DateField(default=date.today, verbose_name="Date")
|
||||
value = models.PositiveSmallIntegerField(default=0)
|
||||
educative = models.ForeignKey(
|
||||
Educative,
|
||||
related_name = "depart_of",
|
||||
verbose_name = "Take-off position",
|
||||
on_delete = models.CASCADE,
|
||||
related_name="depart_of",
|
||||
verbose_name="Take-off position",
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
type_of_evaluator = models.BooleanField(default = 0)
|
||||
evaluator = models.ForeignKey(User, null = True, on_delete = models.SET_NULL)
|
||||
type_of_evaluator = models.BooleanField(default=0)
|
||||
evaluator = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
|
|
@ -1,9 +1,8 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.urls import reverse
|
||||
from django.test import TestCase, Client
|
||||
from django.urls import reverse
|
||||
|
||||
from .models import Routine_Skill, Routine, Skill, TouchPosition
|
||||
from .models import RoutineSkill, Routine, Skill, TouchPosition
|
||||
from .views import link_skill_to_routine
|
||||
|
||||
|
||||
|
@ -51,4 +50,4 @@ class RoutineTest(TestCase):
|
|||
|
||||
# print(response)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
self.assertTrue(Routine_Skill.objects.exists())
|
||||
self.assertTrue(RoutineSkill.objects.exists())
|
|
@ -7,7 +7,7 @@ from . import views
|
|||
# Skills
|
||||
skill_urlpatterns = [
|
||||
re_path(
|
||||
r"^(?P<field>(level|rank|difficulty|landing|rotation|departure|twist))/(?P<expression>[\w]+)/(?P<value>[\w]+)$",
|
||||
r"^(?P<field>(level|rank|difficulty))/(?P<expression>[\w]+)/(?P<value>[\w]+)$",
|
||||
views.skill_listing,
|
||||
name="skill_listing_by_key",
|
||||
),
|
||||
|
@ -42,11 +42,7 @@ routine_urlpatterns = [
|
|||
views.delete_skill_from_routine,
|
||||
name="delete_skill_from_routine",
|
||||
),
|
||||
path(
|
||||
r"suggest/",
|
||||
views.suggest_routine,
|
||||
name="suggest_routine",
|
||||
)
|
||||
path(r"suggest/", views.suggest_routine, name="suggest_routine",),
|
||||
]
|
||||
|
||||
# Chrono
|
|
@ -1,26 +1,24 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.urls import reverse
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
|
||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
from datetime import datetime
|
||||
import math
|
||||
import random
|
||||
|
||||
import simplejson
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.urls import reverse
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.views.decorators.clickjacking import xframe_options_exempt
|
||||
|
||||
from khana.people.models import Gymnast, CanDoRelation
|
||||
|
||||
from .models import Skill, Educative, Routine, Chrono, RoutineSkill
|
||||
from .forms import RoutineForm, ChronoForm
|
||||
from people.models import Gymnast, CanDoRelation
|
||||
|
||||
from datetime import datetime
|
||||
import random
|
||||
|
||||
import math
|
||||
|
||||
|
||||
def __lookup(lookup_class, lookup_value):
|
||||
|
@ -30,7 +28,7 @@ def __lookup(lookup_class, lookup_value):
|
|||
|
||||
:param lookup_class: classe fille dans laquelle la recherche doit être
|
||||
faite.
|
||||
:type lookup_class: string (`skill` ou `routine`).
|
||||
:type lookup_class: string (`skill` ou `routine`).ùpdem
|
||||
:param lookup_value: pattern de recherche.
|
||||
:type lookup_value: string.
|
||||
|
||||
|
@ -261,11 +259,11 @@ def routine_details(request, routineid):
|
|||
if not skill_link.skill.is_competitive:
|
||||
is_competitive = False
|
||||
|
||||
if skill_link.skill.ageBoy is not None and skill_link.skill.ageBoy > age_boy:
|
||||
age_boy = skill_link.skill.ageBoy
|
||||
if skill_link.skill.age_boy is not None and skill_link.skill.age_boy > age_boy:
|
||||
age_boy = skill_link.skill.age_boy
|
||||
|
||||
if skill_link.skill.ageGirl is not None and skill_link.skill.ageGirl > age_girl:
|
||||
age_girl = skill_link.skill.ageGirl
|
||||
if skill_link.skill.age_girl is not None and skill_link.skill.age_girl > age_girl:
|
||||
age_girl = skill_link.skill.age_girl
|
||||
|
||||
if routine.skill_links.all().count() != 10:
|
||||
is_competitive = False
|
||||
|
@ -278,11 +276,11 @@ def routine_details(request, routineid):
|
|||
if routine.rank is None or routine.rank < rank:
|
||||
routine.rank = rank
|
||||
|
||||
if routine.ageBoy is None or routine.ageBoy < age_boy:
|
||||
routine.ageBoy = age_boy
|
||||
if routine.age_boy is None or routine.age_boy < age_boy:
|
||||
routine.age_boy = age_boy
|
||||
|
||||
if routine.ageGirl is None or routine.ageGirl < age_girl:
|
||||
routine.ageGirl = age_girl
|
||||
if routine.age_girl is None or routine.age_girl < age_girl:
|
||||
routine.age_girl = age_girl
|
||||
|
||||
routine.is_competitive = is_competitive
|
||||
|
||||
|
@ -338,7 +336,9 @@ def random_skill(request, skill_quantity=20, is_competitive=True):
|
|||
number_of_skill = skillid_list.count()
|
||||
selected_skillid_list = [
|
||||
skillid_list[x]["id"]
|
||||
for x in [random.randrange(0, number_of_skill, 1) for i in range(skill_quantity)]
|
||||
for x in [
|
||||
random.randrange(0, number_of_skill, 1) for i in range(skill_quantity)
|
||||
]
|
||||
]
|
||||
|
||||
skill_list = Skill.objects.filter(id__in=selected_skillid_list)
|
||||
|
@ -387,12 +387,14 @@ def __construct_routine(
|
|||
|
||||
if current_routine:
|
||||
skill_list = Skill.objects.filter(
|
||||
departure = current_routine[-1].landing
|
||||
) # , difficulty__lte = total_difficulty_score
|
||||
departure=current_routine[-1].landing
|
||||
) # , difficulty__lte = total_difficulty_score
|
||||
if len(current_routine) == (max_routine_length - 1):
|
||||
skill_list = skill_list.filter(landing__longLabel="Debout")
|
||||
if logic and current_routine[-1].landing.longLabel == "Debout":
|
||||
skill_list = skill_list.exclude(rotationType = current_routine[-1].rotationType)
|
||||
skill_list = skill_list.exclude(
|
||||
rotationType=current_routine[-1].rotationType
|
||||
)
|
||||
else:
|
||||
skill_list = Skill.objects.filter(departure__longLabel="Debout")
|
||||
|
||||
|
@ -404,23 +406,31 @@ def __construct_routine(
|
|||
min_diff_skill = total_difficulty_score
|
||||
max_diff_skill = total_difficulty_score + 3
|
||||
else:
|
||||
if math.ceil(total_difficulty_score / max_routine_length) <= max_skill_difficulty:
|
||||
min_diff_skill = math.ceil(max((total_difficulty_score / max_routine_length) - 5, 0))
|
||||
if (
|
||||
math.ceil(total_difficulty_score / max_routine_length)
|
||||
<= max_skill_difficulty
|
||||
):
|
||||
min_diff_skill = math.ceil(
|
||||
max((total_difficulty_score / max_routine_length) - 5, 0)
|
||||
)
|
||||
else:
|
||||
return
|
||||
|
||||
if (math.ceil(total_difficulty_score / max_routine_length) + 2) <= max_skill_difficulty:
|
||||
max_diff_skill = math.ceil(total_difficulty_score / max_routine_length) + 2
|
||||
if (
|
||||
math.ceil(total_difficulty_score / max_routine_length) + 2
|
||||
) <= max_skill_difficulty:
|
||||
max_diff_skill = (
|
||||
math.ceil(total_difficulty_score / max_routine_length) + 2
|
||||
)
|
||||
else:
|
||||
return
|
||||
|
||||
skill_list = skill_list.filter(
|
||||
difficulty__gte = (min_diff_skill / 10),
|
||||
difficulty__lte = (max_diff_skill / 10)
|
||||
difficulty__gte=(min_diff_skill / 10), difficulty__lte=(max_diff_skill / 10)
|
||||
)
|
||||
|
||||
if gymnast:
|
||||
skill_list = skill_list.filter(cando__gymnast = gymnast)
|
||||
skill_list = skill_list.filter(cando__gymnast=gymnast)
|
||||
|
||||
for skill in skill_list:
|
||||
current_routine.append(skill)
|
||||
|
@ -429,7 +439,9 @@ def __construct_routine(
|
|||
current_routine,
|
||||
max_routine_length,
|
||||
max_skill_difficulty,
|
||||
total_difficulty_score - (skill.difficulty * 10) if total_difficulty_score is not None else None,
|
||||
total_difficulty_score - (skill.difficulty * 10)
|
||||
if total_difficulty_score is not None
|
||||
else None,
|
||||
competition,
|
||||
logic,
|
||||
gymnast,
|
||||
|
@ -442,7 +454,7 @@ def __construct_routine(
|
|||
|
||||
def suggest_routine(
|
||||
request,
|
||||
max_routine_length = 2,
|
||||
max_routine_length=2,
|
||||
total_difficulty_score=None,
|
||||
competition=True,
|
||||
logic=True,
|
||||
|
@ -471,24 +483,32 @@ def suggest_routine(
|
|||
total_difficulty_score = 26
|
||||
|
||||
if gymnast:
|
||||
max_skill_difficulty = Educative.objects.values('difficulty').filter(cando__gymnast=gymnast).order_by(
|
||||
"-difficulty"
|
||||
)[:1][0]["difficulty"] * 10
|
||||
max_skill_difficulty = (
|
||||
Educative.objects.values("difficulty")
|
||||
.filter(cando__gymnast=gymnast)
|
||||
.order_by("-difficulty")[:1][0]["difficulty"]
|
||||
* 10
|
||||
)
|
||||
else:
|
||||
max_skill_difficulty = Skill.objects.values('difficulty').order_by("-difficulty")[:1][0]["difficulty"] * 10
|
||||
max_skill_difficulty = (
|
||||
Skill.objects.values("difficulty").order_by("-difficulty")[:1][0][
|
||||
"difficulty"
|
||||
]
|
||||
* 10
|
||||
)
|
||||
|
||||
# difficulty_scores = range(5, 45, 5)
|
||||
# for total_difficulty_score in difficulty_scores:
|
||||
# print("===============================================================================================")
|
||||
__construct_routine(
|
||||
routine,
|
||||
max_routine_length,
|
||||
max_skill_difficulty,
|
||||
total_difficulty_score,
|
||||
competition,
|
||||
logic,
|
||||
gymnast,
|
||||
)
|
||||
routine,
|
||||
max_routine_length,
|
||||
max_skill_difficulty,
|
||||
total_difficulty_score,
|
||||
competition,
|
||||
logic,
|
||||
gymnast,
|
||||
)
|
||||
# print(routines)
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
"""Administration des gymnastes et des personnes.
|
||||
|
||||
Remarks:
|
||||
* Je ne pense pas qu'il faille encore passer par `ForeignKeyAutocompleteAdmin`.
|
||||
https://docs.djangoproject.com/fr/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.autocomplete_fields
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from django_extensions.admin import ForeignKeyAutocompleteAdmin
|
||||
|
||||
from .models import (
|
||||
Gymnast,
|
||||
Accident,
|
||||
CanDoRelation,
|
||||
ToDoRelation,
|
||||
GymnastHasRoutine,
|
||||
)
|
||||
|
||||
|
||||
class CanDoRelationAdmin(ForeignKeyAutocompleteAdmin):
|
||||
model = CanDoRelation
|
||||
|
||||
list_display = ("date", "gymnast", "educative")
|
||||
list_filter = ("gymnast",)
|
||||
search_fields = ("gymnast", "educative")
|
||||
autocomplete_fields = ("gymnast",)
|
||||
|
||||
# related_search_fields = {
|
||||
# 'gymnast': ('lastname', 'firstname'),
|
||||
# }
|
||||
|
||||
|
||||
class InlineCanDoRelation(admin.TabularInline):
|
||||
model = CanDoRelation
|
||||
|
||||
|
||||
class ToDoRelationAdmin(ForeignKeyAutocompleteAdmin):
|
||||
model = ToDoRelation
|
||||
|
||||
list_display = ("date", "gymnast", "educative")
|
||||
list_filter = ("gymnast",)
|
||||
search_fields = ("gymnast", "educative")
|
||||
autocomplete_fields = ("gymnast",)
|
||||
|
||||
# related_search_fields = {
|
||||
# 'gymnast': ('lastname', 'firstname'),
|
||||
# # 'educative': ('longLabel', 'shortLabel'), # TO_FRED : Pq ca marche pas ca ?
|
||||
# }
|
||||
|
||||
|
||||
class GymnastHasRoutineAdmin(ForeignKeyAutocompleteAdmin):
|
||||
model = GymnastHasRoutine
|
||||
|
||||
list_display = ("gymnast", "routine", "routine_type", "datebegin", "dateend")
|
||||
list_filter = ("gymnast", "routine_type")
|
||||
search_fields = ("gymnast", "routine")
|
||||
autocomplete_fields = ("gymnast", "routine")
|
||||
|
||||
|
||||
class InlineToDoRelation(admin.TabularInline):
|
||||
model = ToDoRelation
|
||||
|
||||
|
||||
class GymnastAdmin(admin.ModelAdmin):
|
||||
model = Gymnast
|
||||
|
||||
def lastname(self, obj):
|
||||
return obj.user.last_name
|
||||
|
||||
def firstname(self, obj):
|
||||
return obj.user.first_name
|
||||
|
||||
def email(self, obj):
|
||||
return obj.user.email
|
||||
|
||||
def is_active(self, obj):
|
||||
return obj.user.is_active
|
||||
|
||||
fields = (
|
||||
"user",
|
||||
"birthdate",
|
||||
"gender",
|
||||
"club",
|
||||
"niss",
|
||||
"address",
|
||||
"postal",
|
||||
"city",
|
||||
"phone",
|
||||
"gsm",
|
||||
"federation_id",
|
||||
"year_of_practice",
|
||||
"gsm_main_responsible",
|
||||
"email_main_responsible",
|
||||
"gsm_second_responsible",
|
||||
"email_second_responsible",
|
||||
"orientation",
|
||||
"trainer",
|
||||
"picture",
|
||||
"content",
|
||||
)
|
||||
|
||||
list_display = ("lastname", "firstname", "birthdate", "age", "is_active")
|
||||
list_filter = ("gender", "user__is_active")
|
||||
search_fields = ("lastname", "firstname", "email")
|
||||
inlines = [InlineToDoRelation, InlineCanDoRelation]
|
||||
autocomplete_fields = ("club",)
|
||||
|
||||
|
||||
class AccidentAdmin(admin.ModelAdmin):
|
||||
model = Accident
|
||||
|
||||
fields = ("date", "gymnast", "educative", "information")
|
||||
list_display = ("date", "gymnast", "educative")
|
||||
list_filter = ("date",)
|
||||
search_fields = ("date", "gymnast", "educative")
|
||||
autocomplete_fields = ["gymnast", "educative"]
|
||||
|
||||
|
||||
admin.site.register(Gymnast, GymnastAdmin)
|
||||
admin.site.register(Accident, AccidentAdmin)
|
||||
admin.site.register(CanDoRelation, CanDoRelationAdmin)
|
||||
admin.site.register(ToDoRelation, ToDoRelationAdmin)
|
||||
admin.site.register(GymnastHasRoutine, GymnastHasRoutineAdmin)
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class PeopleConfig(AppConfig):
|
||||
name = "khana.people"
|
|
@ -0,0 +1,175 @@
|
|||
"""Formulaires de gestion des données entrantes pour les gymnastes et accidents."""
|
||||
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from .models import (
|
||||
Accident,
|
||||
Gymnast,
|
||||
GymnastHasRoutine,
|
||||
)
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class AccidentForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Accident
|
||||
fields = ("gymnast", "educative", "date", "content")
|
||||
widgets = {
|
||||
"date": forms.DateInput(
|
||||
attrs={
|
||||
"class": "form-control datepicker",
|
||||
# "value": date.today().strftime("%Y-%m-%d"),
|
||||
}
|
||||
),
|
||||
"gymnast": forms.HiddenInput(),
|
||||
"educative": forms.HiddenInput(),
|
||||
"content": forms.Textarea(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Informations about accident: context (why, where, …), consequencies, …",
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
gymnast_related = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching gymnast…",
|
||||
"data-ref": "#id_gymnast",
|
||||
}
|
||||
)
|
||||
)
|
||||
educative_related = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching skill…",
|
||||
"data-ref": "#id_educative",
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = (
|
||||
"last_name",
|
||||
"first_name",
|
||||
"email",
|
||||
"is_active",
|
||||
"username",
|
||||
)
|
||||
|
||||
|
||||
class GymnastForm(forms.ModelForm):
|
||||
|
||||
lastname = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Lastname"}
|
||||
)
|
||||
)
|
||||
firstname = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Firstname"}
|
||||
)
|
||||
)
|
||||
email = forms.EmailField()
|
||||
# is_active = forms.CheckboxInput()
|
||||
|
||||
class Meta:
|
||||
model = Gymnast
|
||||
fields = (
|
||||
"id",
|
||||
"birthdate",
|
||||
"gender",
|
||||
"address",
|
||||
"postal",
|
||||
"city",
|
||||
"phone",
|
||||
"gsm",
|
||||
"gsm_main_responsible",
|
||||
"email_main_responsible",
|
||||
"gsm_second_responsible",
|
||||
"email_second_responsible",
|
||||
"orientation",
|
||||
"picture",
|
||||
"content",
|
||||
)
|
||||
|
||||
widgets = {
|
||||
"id": forms.HiddenInput(),
|
||||
"lastname": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Lastname"}
|
||||
),
|
||||
"firstname": forms.TextInput(
|
||||
attrs={"class": "form-control", "placeholder": "Firstname"}
|
||||
),
|
||||
"birthdate": forms.DateInput(attrs={"class": "form-control datepicker"}),
|
||||
"gender": forms.Select(attrs={"class": "form-control"}),
|
||||
"address": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"postal": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"city": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"phone": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"gsm": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"email": forms.EmailInput(attrs={"class": "form-control"}),
|
||||
"gsm_main_responsible": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"email_main_responsible": forms.EmailInput(attrs={"class": "form-control"}),
|
||||
"gsm_second_responsible": forms.TextInput(attrs={"class": "form-control"}),
|
||||
"email_second_responsible": forms.EmailInput(
|
||||
attrs={"class": "form-control"}
|
||||
),
|
||||
# "is_active": forms.CheckboxInput(
|
||||
# attrs={
|
||||
# "class": "bootstrap-switch mt-0",
|
||||
# "data-on-label": "<i class='tim-icons icon-check-2 text-success'></i>",
|
||||
# "data-off-label": "<i class='tim-icons icon-simple-remove text-danger'></i>",
|
||||
# }
|
||||
# ),
|
||||
"orientation": forms.Select(attrs={"class": "form-control"}),
|
||||
"picture": forms.Select(attrs={"class": "form-control"}),
|
||||
"content": forms.Textarea(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Informations about the gymnast.",
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
class GymnastHasRoutineForm(forms.ModelForm):
|
||||
"""
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
model = GymnastHasRoutine
|
||||
fields = ("gymnast", "routine", "routine_type", "datebegin", "dateend")
|
||||
widgets = {
|
||||
"gymnast": forms.HiddenInput(),
|
||||
"routine": forms.HiddenInput(),
|
||||
"routine_type": forms.Select(attrs={"class": "form-control"}),
|
||||
"datebegin": forms.DateInput(attrs={"class": "form-control datepicker",}),
|
||||
"dateend": forms.DateInput(attrs={"class": "form-control datepicker",}),
|
||||
}
|
||||
|
||||
gymnast_related = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching gymnast…",
|
||||
"data-ref": "#id_gymnast",
|
||||
}
|
||||
)
|
||||
)
|
||||
routine_related = forms.CharField(
|
||||
widget=forms.TextInput(
|
||||
attrs={
|
||||
"class": "form-control",
|
||||
"placeholder": "Searching routine…",
|
||||
"data-ref": "#id_routine",
|
||||
}
|
||||
)
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue