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]
|
[VARIABLES]
|
||||||
|
|
||||||
django-settings-module=khana.settings
|
django-settings-module=config.settings
|
||||||
|
|
||||||
# List of additional names supposed to be defined in builtins. Remember that
|
# List of additional names supposed to be defined in builtins. Remember that
|
||||||
# you should avoid defining new builtins when possible.
|
# 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:
|
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."
|
@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/
|
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
|
||||||
import os
|
import os
|
||||||
import environ
|
import environ
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
from pathlib import Path
|
||||||
|
|
||||||
env = environ.Env(
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
DEBUG=(bool, False)
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||||
)
|
|
||||||
|
env = environ.Env(DEBUG=(bool, False))
|
||||||
|
|
||||||
environ.Env.read_env()
|
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 = {
|
DATABASES = {"default": env.db("DATABASE_URL", default="sqlite:///db.sqlite3")}
|
||||||
'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 = ["*"]
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
|
|
||||||
# Application definition
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
"django.contrib.contenttypes",
|
"django.contrib.contenttypes",
|
||||||
"django.contrib.admin",
|
"django.contrib.admin",
|
||||||
# 'django.contrib.admindocs',
|
|
||||||
"django.contrib.auth",
|
"django.contrib.auth",
|
||||||
"django.contrib.sessions",
|
"django.contrib.sessions",
|
||||||
"django.contrib.messages",
|
"django.contrib.messages",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"django_extensions",
|
"django_extensions",
|
||||||
"people",
|
"khana.people",
|
||||||
"location",
|
"khana.location",
|
||||||
"planning",
|
"khana.planning",
|
||||||
"objective",
|
"khana.objective",
|
||||||
"competition",
|
"khana.competition",
|
||||||
"profile",
|
"khana.profile",
|
||||||
"tools",
|
"khana.tools",
|
||||||
"communication",
|
"khana.communication",
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
)
|
)
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
#'django.middleware.csrf.CsrfViewMiddleware',
|
#'django.middleware.csrf.CsrfViewMiddleware',
|
||||||
|
@ -66,7 +63,7 @@ MIDDLEWARE = [
|
||||||
#'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
#'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = "khana.urls"
|
ROOT_URLCONF = "config.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
|
@ -107,19 +104,20 @@ LOGIN_URL = "/login/"
|
||||||
|
|
||||||
LOGOUT_URL = "/logout/"
|
LOGOUT_URL = "/logout/"
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
MEDIA_URL = "/media/" # https://media.khana.be
|
||||||
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
|
||||||
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
||||||
|
|
||||||
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
|
|
||||||
STATICFILES_DIRS = (os.path.join(BASE_DIR, "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 = {
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
"JQUERY_URL": STATIC_URL + "js/jquery-2.1.4.min.js",
|
"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.urls import include, path
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from khana import settings
|
|
||||||
|
|
||||||
import khana.views
|
from config import settings
|
||||||
import planning.views
|
|
||||||
import people.views
|
|
||||||
import objective.views
|
|
||||||
import location.views
|
|
||||||
|
|
||||||
import location.urls
|
import config.views
|
||||||
import people.urls
|
import khana.planning.views
|
||||||
import objective.urls
|
import khana.people.views
|
||||||
import planning.urls
|
import khana.objective.views
|
||||||
import competition.urls
|
import khana.location.views
|
||||||
import profile.urls
|
|
||||||
import communication.urls
|
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
|
# import planningline_urlpatterns
|
||||||
|
|
||||||
|
@ -45,45 +46,45 @@ urlpatterns = [
|
||||||
path(r"admin/", admin.site.urls),
|
path(r"admin/", admin.site.urls),
|
||||||
# url(r'^admin/jsi18n/$', include('django.views.i18n.javascript_catalog')), # pour le "ModelMultipleChoiceField" de event.forms
|
# url(r'^admin/jsi18n/$', include('django.views.i18n.javascript_catalog')), # pour le "ModelMultipleChoiceField" de event.forms
|
||||||
# Profile list
|
# Profile list
|
||||||
path(r"profile/", include(profile.urls.profile_urlpatterns)),
|
path(r"profile/", include(khana.profile.urls.profile_urlpatterns)),
|
||||||
# Attendance list
|
# Attendance list
|
||||||
path(r"attendance/", include(planning.urls.attendance_urlpatterns)),
|
path(r"attendance/", include(khana.planning.urls.attendance_urlpatterns)),
|
||||||
# About competition
|
# About competition
|
||||||
path(r"score/", include(competition.urls.score_urlpatterns)),
|
path(r"score/", include(khana.competition.urls.score_urlpatterns)),
|
||||||
# About gymnast
|
# About gymnast
|
||||||
path(r"gymnast/", include(people.urls.people_urlpatterns)),
|
path(r"gymnast/", include(khana.people.urls.people_urlpatterns)),
|
||||||
# About event
|
# About event
|
||||||
path(r"event/", include(planning.urls.event_urlpatterns)),
|
path(r"event/", include(khana.planning.urls.event_urlpatterns)),
|
||||||
# About skill
|
# About skill
|
||||||
path(r"skill/", include(objective.urls.skill_urlpatterns)),
|
path(r"skill/", include(khana.objective.urls.skill_urlpatterns)),
|
||||||
# About chrono
|
# About chrono
|
||||||
path(r"chrono/", include(objective.urls.chrono_urlpatterns)),
|
path(r"chrono/", include(khana.objective.urls.chrono_urlpatterns)),
|
||||||
# About skill
|
# About skill
|
||||||
path(r"training/", include(planning.urls.training_urlpatterns)),
|
path(r"training/", include(khana.planning.urls.training_urlpatterns)),
|
||||||
# About routine
|
# About routine
|
||||||
path(r"routine/", include(objective.urls.routine_urlpatterns)),
|
path(r"routine/", include(khana.objective.urls.routine_urlpatterns)),
|
||||||
# About accident
|
# About accident
|
||||||
path(r"accident/", include(people.urls.accident_urlpatterns)),
|
path(r"accident/", include(khana.people.urls.accident_urlpatterns)),
|
||||||
# About unavailability
|
# About unavailability
|
||||||
path(r"unavailability/", include(planning.urls.unavailability_urlpatterns)),
|
path(r"unavailability/", include(khana.planning.urls.unavailability_urlpatterns)),
|
||||||
# About planningline
|
# About planningline
|
||||||
path(r"program/", include(planning.urls.planningline_urlpatterns)),
|
path(r"program/", include(khana.planning.urls.planningline_urlpatterns)),
|
||||||
# About course
|
# About course
|
||||||
path(r"course/", include(planning.urls.course_urlpatterns)),
|
path(r"course/", include(khana.planning.urls.course_urlpatterns)),
|
||||||
path(r"messages/", include(communication.urls.message_urlpatterns)),
|
path(r"messages/", include(khana.communication.urls.message_urlpatterns)),
|
||||||
# About Location
|
# About Location
|
||||||
path(r"place/", include(location.urls.place_urlpatterns)),
|
path(r"place/", include(khana.location.urls.place_urlpatterns)),
|
||||||
path(r"country/", include(location.urls.country_urlpatterns)),
|
path(r"country/", include(khana.location.urls.country_urlpatterns)),
|
||||||
path(r"club/", include(location.urls.club_urlpatterns)),
|
path(r"club/", include(khana.location.urls.club_urlpatterns)),
|
||||||
# url(r'^club/', location.views.chooseStatistics),
|
# url(r'^club/', location.views.chooseStatistics),
|
||||||
# url(r'^club/(?P<clubid>[0-9]+)', location.views.club_statistics),
|
# url(r'^club/(?P<clubid>[0-9]+)', location.views.club_statistics),
|
||||||
# Global search
|
# Global search
|
||||||
path(r"search/", khana.views.search, name="global_search"),
|
path(r"search/", config.views.search, name="global_search"),
|
||||||
# login & logout
|
# login & logout
|
||||||
path(r"login/", khana.views.login, name="login"),
|
path(r"login/", config.views.login, name="login"),
|
||||||
path(r"logout/", khana.views.logout, name="logout"),
|
path(r"logout/", config.views.logout, name="logout"),
|
||||||
# Home page
|
# 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)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|
||||||
# if settings.DEBUG:
|
# 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.db.models import Q
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
|
@ -9,23 +13,20 @@ from django.http import HttpResponseRedirect
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
|
|
||||||
from datetime import datetime, timedelta, date
|
import pendulum
|
||||||
from functools import reduce
|
|
||||||
import operator
|
|
||||||
|
|
||||||
from planning.models import (
|
from khana.planning.models import (
|
||||||
Season,
|
Season,
|
||||||
Event,
|
Event,
|
||||||
Unavailability,
|
Unavailability,
|
||||||
Course,
|
Course,
|
||||||
get_number_of_weeks_between,
|
get_number_of_weeks_between,
|
||||||
)
|
)
|
||||||
from people.models import Gymnast, Accident # people model
|
from khana.people.models import Gymnast, Accident # people model
|
||||||
from location.models import Club # location model
|
from khana.location.models import Club # location model
|
||||||
from objective.models import Skill, Routine # objective model
|
from khana.objective.models import Skill, Routine # objective model
|
||||||
from profile.models import Profile
|
from khana.profile.models import Profile
|
||||||
from communication.views import get_number_of_unread_message
|
from khana.communication.views import get_number_of_unread_message
|
||||||
import pendulum
|
|
||||||
|
|
||||||
|
|
||||||
def login(request):
|
def login(request):
|
||||||
|
@ -49,7 +50,7 @@ def login(request):
|
||||||
request.session["template"] = profile.template_color
|
request.session["template"] = profile.template_color
|
||||||
request.session["sidebar"] = profile.sidebar_color
|
request.session["sidebar"] = profile.sidebar_color
|
||||||
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
||||||
except expression as identifier:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
request.session["clubid"] = request.POST.get("clubid", None)
|
request.session["clubid"] = request.POST.get("clubid", None)
|
||||||
return HttpResponseRedirect("/")
|
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 ?
|
.. 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)
|
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)
|
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
|
return next_event_list
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,9 +131,18 @@ def __getCourseInfo(request):
|
||||||
else:
|
else:
|
||||||
rest = int((tmp.days + 1) / 7)
|
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_left += rest
|
||||||
courses_done += counted - rest
|
courses_done += counted - rest
|
||||||
|
|
||||||
|
# courses.append((course, counted, (counted - rest)))
|
||||||
|
|
||||||
return courses, courses_done, courses_left
|
return courses, courses_done, courses_left
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,10 +160,10 @@ def home(request):
|
||||||
try:
|
try:
|
||||||
season = Season.objects.get(datebegin__lte=today, dateend__gte=today)
|
season = Season.objects.get(datebegin__lte=today, dateend__gte=today)
|
||||||
except Season.DoesNotExist:
|
except Season.DoesNotExist:
|
||||||
context = {"error": "No season founded."}
|
context = {"error": "No season found."}
|
||||||
return render(request, "index.html", context)
|
return render(request, "index.html", context)
|
||||||
except Season.MultipleObjectsReturned:
|
except Season.MultipleObjectsReturned:
|
||||||
context = {"error": "Multiple season founded."}
|
context = {"error": "Multiple season found."}
|
||||||
return render(request, "index.html", context)
|
return render(request, "index.html", context)
|
||||||
|
|
||||||
week_number = season.week_number_from_begin(today)
|
week_number = season.week_number_from_begin(today)
|
||||||
|
@ -222,7 +247,8 @@ def search(request):
|
||||||
name__icontains=pattern
|
name__icontains=pattern
|
||||||
) # ou gymnaste qui y participe !
|
) # ou gymnaste qui y participe !
|
||||||
gymnast_list = Gymnast.objects.filter(
|
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(
|
accident_list = Accident.objects.filter(
|
||||||
Q(gymnast__user__last_name__icontains=pattern)
|
Q(gymnast__user__last_name__icontains=pattern)
|
|
@ -11,6 +11,6 @@ import os
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
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()
|
application = get_wsgi_application()
|
|
@ -9,6 +9,7 @@ from .models import Message
|
||||||
class MessageAdmin(admin.ModelAdmin):
|
class MessageAdmin(admin.ModelAdmin):
|
||||||
"""La classe `MessageAdmin` contrôle la gestion des messages
|
"""La classe `MessageAdmin` contrôle la gestion des messages
|
||||||
"""
|
"""
|
||||||
|
|
||||||
list_display = ("sender", "recipient", "written_at", "is_read", "read_at")
|
list_display = ("sender", "recipient", "written_at", "is_read", "read_at")
|
||||||
ordering = ("written_at", "sender")
|
ordering = ("written_at", "sender")
|
||||||
search_fields = ("sender", "recipient", "message_title")
|
search_fields = ("sender", "recipient", "message_title")
|
|
@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class CommunicationConfig(AppConfig):
|
class CommunicationConfig(AppConfig):
|
||||||
name = "communication"
|
name = "khana.communication"
|
|
@ -8,6 +8,7 @@ from .models import Message
|
||||||
class MessageForm(forms.ModelForm):
|
class MessageForm(forms.ModelForm):
|
||||||
"""Formulaire de base pour la création et la modification de messages
|
"""Formulaire de base pour la création et la modification de messages
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Message
|
model = Message
|
||||||
fields = (
|
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.db import models
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
from base.models import Markdownizable
|
from khana.base.models import Markdownizable
|
||||||
|
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
@ -33,13 +33,11 @@ class Message(Markdownizable):
|
||||||
sender = models.ForeignKey(
|
sender = models.ForeignKey(
|
||||||
User, on_delete=models.CASCADE, related_name="sent_messages"
|
User, on_delete=models.CASCADE, related_name="sent_messages"
|
||||||
)
|
)
|
||||||
written_at = models.DateTimeField(
|
written_at = models.DateTimeField(auto_now_add=True, verbose_name="Date of writing")
|
||||||
auto_now_add=True, verbose_name="Date of writing"
|
recipient = models.ForeignKey(
|
||||||
)
|
User, on_delete=models.CASCADE, related_name="received_messages"
|
||||||
recipient = models.ForeignKey(User, on_delete=models.CASCADE, related_name="received_messages")
|
|
||||||
read_at = models.DateTimeField(
|
|
||||||
auto_now=True, verbose_name="Date of reading"
|
|
||||||
)
|
)
|
||||||
|
read_at = models.DateTimeField(auto_now=True, verbose_name="Date of reading")
|
||||||
title = models.CharField(max_length=255, verbose_name="Title")
|
title = models.CharField(max_length=255, verbose_name="Title")
|
||||||
body = models.TextField(null=True, blank=True, verbose_name="Message")
|
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
|
"""Vérifie la représentation textuelle d'un message
|
||||||
"""
|
"""
|
||||||
timing = datetime.now()
|
timing = datetime.now()
|
||||||
user = User(username='fred', password='fredpassword')
|
user = User(username="fred", password="fredpassword")
|
||||||
message = Message(sender=user, written_at=timing, title="test")
|
message = Message(sender=user, written_at=timing, title="test")
|
||||||
assert str(message) == "fred - " + str(timing) + " : 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",
|
"total",
|
||||||
)
|
)
|
||||||
ordering = ("gymnast",)
|
ordering = ("gymnast",)
|
||||||
# search_fields = ('longLabel', 'shortLabel')
|
|
||||||
list_filter = ("gymnast", "event", "routine_type")
|
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
|
from django.db import models
|
||||||
|
|
||||||
|
@ -14,7 +13,6 @@ class Point(models.Model):
|
||||||
"people.Gymnast", on_delete=models.CASCADE, default=None
|
"people.Gymnast", on_delete=models.CASCADE, default=None
|
||||||
)
|
)
|
||||||
event = models.ForeignKey("planning.Event", 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)
|
routine_type = models.PositiveSmallIntegerField(choices=ROUTINETYPE_CHOICE)
|
||||||
point_execution = models.DecimalField(max_digits=5, decimal_places=3)
|
point_execution = models.DecimalField(max_digits=5, decimal_places=3)
|
||||||
point_difficulty = models.DecimalField(max_digits=3, decimal_places=1)
|
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)
|
total = models.DecimalField(max_digits=6, decimal_places=3)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s, %s - %s" % (
|
return "%s - %s" % (
|
||||||
self.gymnast.lastname,
|
self.gymnast,
|
||||||
self.gymnast.firstname,
|
|
||||||
self.total,
|
self.total,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
# coding=UTF-8
|
# coding=UTF-8
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from .models import (
|
from .models import Point, Competition, Division, Level
|
||||||
Point,
|
|
||||||
Competition,
|
|
||||||
Division,
|
|
||||||
Level
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# class TestModelCompetition(TestCase):
|
# class TestModelCompetition(TestCase):
|
||||||
|
@ -14,6 +9,7 @@ from .models import (
|
||||||
# Tests relatifs à la classe `Compétition`.
|
# Tests relatifs à la classe `Compétition`.
|
||||||
# """
|
# """
|
||||||
|
|
||||||
|
|
||||||
def test_competition_str_():
|
def test_competition_str_():
|
||||||
""" Vérifie la représentation textuelle de la classe. """
|
""" Vérifie la représentation textuelle de la classe. """
|
||||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
||||||
|
@ -25,6 +21,7 @@ def test_competition_str_():
|
||||||
# Tests relatifs à la classe `Division`.
|
# Tests relatifs à la classe `Division`.
|
||||||
# """
|
# """
|
||||||
|
|
||||||
|
|
||||||
def test_division_str_():
|
def test_division_str_():
|
||||||
""" Vérifie la représentation textuelle de la classe. """
|
""" Vérifie la représentation textuelle de la classe. """
|
||||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
||||||
|
@ -37,6 +34,7 @@ def test_division_str_():
|
||||||
# Tests relatifs à la classe `Level`.
|
# Tests relatifs à la classe `Level`.
|
||||||
# """
|
# """
|
||||||
|
|
||||||
|
|
||||||
def test_level_str_():
|
def test_level_str_():
|
||||||
""" Vérifie la représentation textuelle de la classe. """
|
""" Vérifie la représentation textuelle de la classe. """
|
||||||
competition = Competition(name="Belgian Open Trampoline", acronym="BOT")
|
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.shortcuts import render, get_object_or_404
|
||||||
from django.contrib.auth.decorators import login_required
|
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.views.decorators.http import require_http_methods
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from khana.people.models import Gymnast
|
||||||
|
|
||||||
from .forms import ScoreForm
|
from .forms import ScoreForm
|
||||||
from .models import Point
|
from .models import Point
|
||||||
from people.models import Gymnast
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@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):
|
class TestCountry(TestCase):
|
||||||
def test_str_should_contain_name_and_iso2(self):
|
def test_str_should_contain_name_and_iso2(self):
|
||||||
country = Country.objects.create(
|
country = Country.objects.create(
|
||||||
nameus="Belgium",
|
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||||
namefr="Belgique",
|
|
||||||
isonum=56,
|
|
||||||
iso2="BE"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(str(country), "Belgique (BE)")
|
self.assertEqual(str(country), "Belgique (BE)")
|
||||||
|
@ -23,11 +20,8 @@ class TestPlace(TestCase):
|
||||||
name="Heaven",
|
name="Heaven",
|
||||||
postal=1080,
|
postal=1080,
|
||||||
country=Country.objects.create(
|
country=Country.objects.create(
|
||||||
nameus="Belgium",
|
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||||
namefr="Belgique",
|
),
|
||||||
isonum=56,
|
|
||||||
iso2="BE"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(str(place), "Heaven (?)")
|
self.assertEqual(str(place), "Heaven (?)")
|
||||||
|
@ -41,12 +35,9 @@ class TestClub(TestCase):
|
||||||
name="Heaven",
|
name="Heaven",
|
||||||
postal=1080,
|
postal=1080,
|
||||||
country=Country.objects.create(
|
country=Country.objects.create(
|
||||||
nameus="Belgium",
|
nameus="Belgium", namefr="Belgique", isonum=56, iso2="BE"
|
||||||
namefr="Belgique",
|
),
|
||||||
isonum=56,
|
),
|
||||||
iso2="BE"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(str(club), "RSCA (à ?)")
|
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 datetime import datetime, timedelta, date
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
import operator
|
import operator
|
||||||
import simplejson
|
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,
|
Event,
|
||||||
Unavailability,
|
Unavailability,
|
||||||
Course,
|
Course,
|
||||||
Subgroup,
|
Subgroup,
|
||||||
Training,
|
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 (
|
from .models import (
|
||||||
Club,
|
Club,
|
||||||
Country,
|
|
||||||
GymnastStatistics,
|
|
||||||
Place,
|
Place,
|
||||||
|
Country,
|
||||||
)
|
)
|
||||||
from .forms import PlaceForm
|
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
|
@login_required
|
||||||
|
@ -78,7 +88,7 @@ def place_listing(request):
|
||||||
"""
|
"""
|
||||||
place_list = Place.objects.all()
|
place_list = Place.objects.all()
|
||||||
context = {"place_list": place_list}
|
context = {"place_list": place_list}
|
||||||
return render(request, "place_list.html", context)
|
return render(request, "places/list.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -106,7 +116,7 @@ def place_create_or_update(request, placeid=None):
|
||||||
form = PlaceForm(instance=place, initial=data)
|
form = PlaceForm(instance=place, initial=data)
|
||||||
|
|
||||||
context = {"form": form, "placeid": placeid}
|
context = {"form": form, "placeid": placeid}
|
||||||
return render(request, "place_create.html", context)
|
return render(request, "places/create.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -117,7 +127,7 @@ def place_details(request, placeid):
|
||||||
"""
|
"""
|
||||||
place = get_object_or_404(Place, pk=placeid)
|
place = get_object_or_404(Place, pk=placeid)
|
||||||
context = {"place": place}
|
context = {"place": place}
|
||||||
return render(request, "place_details.html", context)
|
return render(request, "places/details.html", context)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -144,133 +154,11 @@ def chooseStatistics(request):
|
||||||
return render(request, "club_statistics.html", context)
|
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
|
@login_required
|
||||||
def club_statistics(request, clubid):
|
def club_statistics(request, clubid):
|
||||||
"""
|
"""
|
||||||
Renvoie les statistiques d'un club pour une saison choisie.
|
Renvoie les statistiques d'un club pour une saison choisie.
|
||||||
|
|
||||||
.. todo:: tenir compte de la saison.
|
.. todo:: tenir compte de la saison.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -285,9 +173,8 @@ def club_statistics(request, clubid):
|
||||||
gymnastsDict = {}
|
gymnastsDict = {}
|
||||||
gymnasts = []
|
gymnasts = []
|
||||||
courseList = []
|
courseList = []
|
||||||
|
|
||||||
for course in courses:
|
for course in courses:
|
||||||
|
nbtrainer = course.trainers.count()
|
||||||
list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
|
list_of_gymnasts = Gymnast.objects.filter(to_gym__in=course.to_subgroup.all())
|
||||||
gymnasts.extend(list_of_gymnasts)
|
gymnasts.extend(list_of_gymnasts)
|
||||||
nbgymnast = len(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
|
nbhour = __diffTime(course.hour_end, course.hour_begin) # timedelta
|
||||||
totalHoursByWeek += nbhour.seconds
|
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
|
hour = nbhour.seconds / 3600
|
||||||
|
|
||||||
|
courseList.append(
|
||||||
|
(
|
||||||
|
course,
|
||||||
|
nbtrainer,
|
||||||
|
nbgymnast,
|
||||||
|
hour,
|
||||||
|
counted,
|
||||||
|
totalHourForCourse,
|
||||||
|
totalHoursPaidForCourse,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
for gymnast in list_of_gymnasts:
|
for gymnast in list_of_gymnasts:
|
||||||
# print(gymnast)
|
# print(gymnast)
|
||||||
if gymnast.id not in gymnastsDict:
|
if gymnast.id not in gymnastsDict:
|
||||||
|
@ -320,10 +237,14 @@ def club_statistics(request, clubid):
|
||||||
|
|
||||||
# print(str(gymnast) + ' : ' + str(nbattendance) + ' for ' + str(course) )
|
# print(str(gymnast) + ' : ' + str(nbattendance) + ' for ' + str(course) )
|
||||||
|
|
||||||
|
gymnastsDict[gymnast.id]["nbcoursebyweek"] += 1
|
||||||
gymnastsDict[gymnast.id]["nbhourbyweek"] += nbhour # timedelta
|
gymnastsDict[gymnast.id]["nbhourbyweek"] += nbhour # timedelta
|
||||||
|
gymnastsDict[gymnast.id]["nbtraining"] += counted
|
||||||
gymnastsDict[gymnast.id]["nbattendance"] += nbattendance
|
gymnastsDict[gymnast.id]["nbattendance"] += nbattendance
|
||||||
gymnastsDict[gymnast.id]["nbhourtraining"] += totalHourForCourse
|
gymnastsDict[gymnast.id]["nbhourtraining"] += totalHourForCourse
|
||||||
|
gymnastsDict[gymnast.id]["nbhourattendance"] += (
|
||||||
|
nbhour * nbattendance
|
||||||
|
) # timedelta
|
||||||
|
|
||||||
# print(gymnastsDict[gymnast.id])
|
# print(gymnastsDict[gymnast.id])
|
||||||
|
|
||||||
|
@ -379,4 +300,3 @@ def club_statistics(request, clubid):
|
||||||
"totalHoursPaid": totalHoursPaid,
|
"totalHoursPaid": totalHoursPaid,
|
||||||
}
|
}
|
||||||
return context
|
return context
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from people.models import Gymnast
|
from khana.people.models import Gymnast
|
||||||
from objectives.models import Skill
|
from khana.objective.models import Skill
|
||||||
|
|
||||||
|
|
||||||
def suggest_routine(
|
def suggest_routine(
|
||||||
|
@ -58,16 +59,17 @@ def suggest_routine(
|
||||||
for skill in skill_list:
|
for skill in skill_list:
|
||||||
current_routine.append(skill)
|
current_routine.append(skill)
|
||||||
current_routine.append(
|
current_routine.append(
|
||||||
self.suggest_routine(
|
None
|
||||||
request,
|
# suggest_routine()
|
||||||
total_difficulty_score - skill.difficulty,
|
# request,
|
||||||
max_difficulty_score,
|
# total_difficulty_score - skill.difficulty,
|
||||||
routine_length - 1,
|
# max_difficulty_score,
|
||||||
competition,
|
# routine_length - 1,
|
||||||
logic,
|
# competition,
|
||||||
gymnast,
|
# logic,
|
||||||
skill,
|
# gymnast,
|
||||||
)
|
# skill,
|
||||||
|
# )
|
||||||
)
|
)
|
||||||
current_routine.pop()
|
current_routine.pop()
|
||||||
# def knapSack(W, wt, val, n):
|
# def knapSack(W, wt, val, n):
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Educative,
|
Educative,
|
||||||
TouchPosition,
|
TouchPosition,
|
||||||
|
@ -30,12 +30,8 @@ def duplicate_skill(self, SkillAdmin, request, queryset):
|
||||||
class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
||||||
model = Skill
|
model = Skill
|
||||||
|
|
||||||
# related_search_fields = {
|
|
||||||
# 'departure': ('label', 'short_label'),
|
|
||||||
# 'landing': ('label', 'short_label')
|
|
||||||
# }
|
|
||||||
fields = (
|
fields = (
|
||||||
"label",
|
"long_label",
|
||||||
"short_label",
|
"short_label",
|
||||||
"information",
|
"information",
|
||||||
"departure",
|
"departure",
|
||||||
|
@ -57,7 +53,7 @@ class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
||||||
)
|
)
|
||||||
|
|
||||||
list_display = (
|
list_display = (
|
||||||
"label",
|
"long_label",
|
||||||
"difficulty",
|
"difficulty",
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
"level",
|
"level",
|
||||||
|
@ -66,9 +62,9 @@ class SkillAdmin(ForeignKeyAutocompleteAdmin):
|
||||||
"age_boy",
|
"age_boy",
|
||||||
"age_girl",
|
"age_girl",
|
||||||
)
|
)
|
||||||
# list_display = ('label', 'short_label', 'prerequisite')
|
|
||||||
ordering = ("label", "short_label")
|
ordering = ("long_label", "short_label")
|
||||||
search_fields = ("rank", "label", "short_label")
|
search_fields = ("rank", "long_label", "short_label")
|
||||||
list_filter = (
|
list_filter = (
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
"departure",
|
"departure",
|
||||||
|
@ -94,7 +90,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
model = Routine
|
model = Routine
|
||||||
|
|
||||||
fields = (
|
fields = (
|
||||||
"label",
|
"long_label",
|
||||||
"short_label",
|
"short_label",
|
||||||
"difficulty",
|
"difficulty",
|
||||||
"level",
|
"level",
|
||||||
|
@ -107,7 +103,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
)
|
)
|
||||||
list_display = (
|
list_display = (
|
||||||
"label",
|
"long_label",
|
||||||
"short_label",
|
"short_label",
|
||||||
"is_competitive",
|
"is_competitive",
|
||||||
"active",
|
"active",
|
||||||
|
@ -117,7 +113,7 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
)
|
)
|
||||||
list_filter = ("level", "difficulty", "is_competitive", "active")
|
list_filter = ("level", "difficulty", "is_competitive", "active")
|
||||||
search_fields = (
|
search_fields = (
|
||||||
"label",
|
"long_label",
|
||||||
"short_label",
|
"short_label",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -127,10 +123,10 @@ class RoutineAdmin(admin.ModelAdmin):
|
||||||
js = ("js/routine.js",)
|
js = ("js/routine.js",)
|
||||||
|
|
||||||
# TODO: ne proposer QUE les SKILL comme educatif
|
# TODO: ne proposer QUE les SKILL comme educatif
|
||||||
def get_related_filter(self, model, request):
|
# def get_related_filter(self, model, request):
|
||||||
# print('boum')
|
# # print('boum')
|
||||||
if not issubclass(model, Educative):
|
# if not issubclass(model, Educative):
|
||||||
return super(Skill, self).get_related_filter(model, request)
|
# return super(Skill, self).get_related_filter(model, request)
|
||||||
|
|
||||||
|
|
||||||
class RoutineSkillAdmin(admin.ModelAdmin):
|
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 RoutineForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Routine
|
model = Routine
|
||||||
fields = ("label", "label", "difficulty", "level", "active")
|
fields = ("long_label", "short_label", "difficulty", "level", "active")
|
||||||
widgets = {
|
widgets = {
|
||||||
# Champs obligatoires de la classe mère.
|
# Champs obligatoires de la classe mère.
|
||||||
"label": forms.TextInput(
|
"long_label": forms.TextInput(
|
||||||
attrs={"class": "form-control", "placeholder": "Routine's long name"}
|
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"}
|
attrs={"class": "form-control", "placeholder": "Routine's short name"}
|
||||||
),
|
),
|
||||||
"difficulty": forms.HiddenInput(),
|
"difficulty": forms.HiddenInput(),
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import objective.models
|
import khana.objective.models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -28,7 +28,7 @@ class Migration(migrations.Migration):
|
||||||
model_name="skill",
|
model_name="skill",
|
||||||
name="departure",
|
name="departure",
|
||||||
field=models.ForeignKey(
|
field=models.ForeignKey(
|
||||||
default=objective.models.get_default_position,
|
default=khana.objective.models.get_default_position,
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
related_name="depart_of",
|
related_name="depart_of",
|
||||||
to="objective.TouchPosition",
|
to="objective.TouchPosition",
|
||||||
|
@ -39,7 +39,7 @@ class Migration(migrations.Migration):
|
||||||
model_name="skill",
|
model_name="skill",
|
||||||
name="landing",
|
name="landing",
|
||||||
field=models.ForeignKey(
|
field=models.ForeignKey(
|
||||||
default=objective.models.get_default_position,
|
default=khana.objective.models.get_default_position,
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
related_name="landing_of",
|
related_name="landing_of",
|
||||||
to="objective.TouchPosition",
|
to="objective.TouchPosition",
|
|
@ -6,13 +6,11 @@ from django.db import migrations
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('objective', '0015_auto_20190524_1211'),
|
("objective", "0015_auto_20190524_1211"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RenameField(
|
migrations.RenameField(
|
||||||
model_name='educative',
|
model_name="educative", old_name="information", new_name="content",
|
||||||
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 datetime import date
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q
|
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):
|
class Educative(Markdownizable):
|
||||||
|
@ -12,35 +15,76 @@ class Educative(Markdownizable):
|
||||||
Classe `mère`.
|
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:
|
class Meta:
|
||||||
verbose_name = "Educatif"
|
verbose_name = "Educatif"
|
||||||
verbose_name_plural = "Educatifs"
|
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")
|
long_label = models.CharField(max_length=255, verbose_name="Long Name")
|
||||||
short_label = models.CharField(max_length = 255, verbose_name = "Short Name")
|
short_label = models.CharField(max_length=255, verbose_name="Short Name")
|
||||||
difficulty = models.DecimalField(
|
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)
|
level = models.PositiveSmallIntegerField(verbose_name="Level", default=0)
|
||||||
rank = models.PositiveSmallIntegerField(verbose_name = "Rank", default = 0)
|
rank = models.PositiveSmallIntegerField(verbose_name="Rank", default=0)
|
||||||
educatives = models.ManyToManyField(
|
educatives = models.ManyToManyField(
|
||||||
"self", related_name = "educativeOf", blank = True, symmetrical = False
|
"self", related_name="educativeOf", blank=True, symmetrical=False
|
||||||
)
|
)
|
||||||
prerequisites = models.ManyToManyField(
|
prerequisites = models.ManyToManyField(
|
||||||
"self", related_name = "prerequisiteOf", blank = True, symmetrical = False
|
"self", related_name="prerequisiteOf", blank=True, symmetrical=False
|
||||||
)
|
)
|
||||||
age_boy = models.PositiveSmallIntegerField(
|
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(
|
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):
|
def __str__(self):
|
||||||
return "%s - %s (level: %s | diff: %s)" % (
|
return "%s - %s (level: %s | diff: %s)" % (
|
||||||
self.rank,
|
self.rank,
|
||||||
self.longLabel,
|
self.label,
|
||||||
self.level,
|
self.level,
|
||||||
self.difficulty,
|
self.difficulty,
|
||||||
)
|
)
|
||||||
|
@ -56,13 +100,13 @@ class TouchPosition(models.Model):
|
||||||
verbose_name_plural = "Landings"
|
verbose_name_plural = "Landings"
|
||||||
ordering = ["label", "short_label", "is_default", "allowed_in_competition"]
|
ordering = ["label", "short_label", "is_default", "allowed_in_competition"]
|
||||||
|
|
||||||
label = models.CharField(max_length = 30, verbose_name = "Nom long")
|
label = models.CharField(max_length=30, verbose_name="Nom long")
|
||||||
short_label = models.CharField(max_length = 15, verbose_name = "Nom court")
|
short_label = models.CharField(max_length=15, verbose_name="Nom court")
|
||||||
allowed_in_competition = models.BooleanField(verbose_name = "Compétition")
|
allowed_in_competition = models.BooleanField(verbose_name="Compétition")
|
||||||
is_default = models.BooleanField(verbose_name = "Défaut")
|
is_default = models.BooleanField(verbose_name="Défaut")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s" % (self.longLabel)
|
return "%s" % (self.label)
|
||||||
|
|
||||||
|
|
||||||
def get_default_position():
|
def get_default_position():
|
||||||
|
@ -104,29 +148,31 @@ class Skill(Educative):
|
||||||
(2, "Backward"),
|
(2, "Backward"),
|
||||||
)
|
)
|
||||||
|
|
||||||
position = models.CharField(max_length = 2, choices = POSITION_CHOICES)
|
position = models.CharField(max_length=2, choices=POSITION_CHOICES)
|
||||||
departure = models.ForeignKey(
|
departure = models.ForeignKey(
|
||||||
TouchPosition,
|
TouchPosition,
|
||||||
related_name = "depart_of",
|
related_name="depart_of",
|
||||||
default = get_default_position,
|
default=get_default_position,
|
||||||
verbose_name = "Take-off position",
|
verbose_name="Take-off position",
|
||||||
on_delete = models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
landing = models.ForeignKey(
|
landing = models.ForeignKey(
|
||||||
TouchPosition,
|
TouchPosition,
|
||||||
related_name = "landing_of",
|
related_name="landing_of",
|
||||||
default = get_default_position,
|
default=get_default_position,
|
||||||
verbose_name = "Landing position",
|
verbose_name="Landing position",
|
||||||
on_delete = models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
rotation_type = models.PositiveSmallIntegerField(
|
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")
|
rotation = models.PositiveSmallIntegerField(verbose_name="1/4 de rotation")
|
||||||
twist = models.PositiveSmallIntegerField(verbose_name = "1/2 Vrille")
|
twist = models.PositiveSmallIntegerField(verbose_name="1/2 Vrille")
|
||||||
notation = models.CharField(max_length = 25)
|
notation = models.CharField(max_length=25)
|
||||||
simplified_notation = models.CharField(max_length = 25, verbose_name = "Notation simplifiée")
|
simplified_notation = models.CharField(
|
||||||
is_competitive = models.BooleanField(default = False)
|
max_length=25, verbose_name="Notation simplifiée"
|
||||||
|
)
|
||||||
|
is_competitive = models.BooleanField(default=False)
|
||||||
# importance = models.PositiveSmallIntegerField(default = 1)
|
# importance = models.PositiveSmallIntegerField(default = 1)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -144,12 +190,12 @@ class Routine(Educative):
|
||||||
|
|
||||||
active = models.BooleanField()
|
active = models.BooleanField()
|
||||||
jumps = models.ManyToManyField(
|
jumps = models.ManyToManyField(
|
||||||
Skill, through = "RoutineSkill", verbose_name = "routine"
|
Skill, through="RoutineSkill", verbose_name="routine"
|
||||||
) # ceci n'est pas un vrai champ
|
) # ceci n'est pas un vrai champ
|
||||||
is_competitive = models.BooleanField(default = False)
|
is_competitive = models.BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
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):
|
def contains_basic_jumps(self):
|
||||||
"""
|
"""
|
||||||
|
@ -216,10 +262,10 @@ class RoutineSkill(models.Model):
|
||||||
ordering = ("rank",)
|
ordering = ("rank",)
|
||||||
|
|
||||||
routine = models.ForeignKey(
|
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 = 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()
|
rank = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
|
@ -247,13 +293,13 @@ class Chrono(models.Model):
|
||||||
(99, "Other"),
|
(99, "Other"),
|
||||||
)
|
)
|
||||||
|
|
||||||
routine = models.ForeignKey(Routine, on_delete = models.CASCADE, default = None)
|
routine = models.ForeignKey(Routine, on_delete=models.CASCADE, default=None)
|
||||||
routine_type = models.PositiveSmallIntegerField(choices = ROUTINETYPE_CHOICE)
|
routine_type = models.PositiveSmallIntegerField(choices=ROUTINETYPE_CHOICE)
|
||||||
gymnast = models.ForeignKey(
|
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")
|
date = models.DateField(default=date.today, verbose_name="Date")
|
||||||
score = models.DecimalField(max_digits = 5, decimal_places = 2)
|
score = models.DecimalField(max_digits=5, decimal_places=2)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s le %s : %s pour %s" % (
|
return "%s le %s : %s pour %s" % (
|
||||||
|
@ -278,13 +324,13 @@ class Evaluation(models.Model):
|
||||||
Classe permettant l'évaluation des éducatifs.
|
Classe permettant l'évaluation des éducatifs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
date = models.DateField(default = date.today, verbose_name = "Date")
|
date = models.DateField(default=date.today, verbose_name="Date")
|
||||||
value = models.PositiveSmallIntegerField(default = 0)
|
value = models.PositiveSmallIntegerField(default=0)
|
||||||
educative = models.ForeignKey(
|
educative = models.ForeignKey(
|
||||||
Educative,
|
Educative,
|
||||||
related_name = "depart_of",
|
related_name="depart_of",
|
||||||
verbose_name = "Take-off position",
|
verbose_name="Take-off position",
|
||||||
on_delete = models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
type_of_evaluator = models.BooleanField(default = 0)
|
type_of_evaluator = models.BooleanField(default=0)
|
||||||
evaluator = models.ForeignKey(User, null = True, on_delete = models.SET_NULL)
|
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.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
|
from .views import link_skill_to_routine
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,4 +50,4 @@ class RoutineTest(TestCase):
|
||||||
|
|
||||||
# print(response)
|
# print(response)
|
||||||
self.assertEquals(response.status_code, 200)
|
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
|
# Skills
|
||||||
skill_urlpatterns = [
|
skill_urlpatterns = [
|
||||||
re_path(
|
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,
|
views.skill_listing,
|
||||||
name="skill_listing_by_key",
|
name="skill_listing_by_key",
|
||||||
),
|
),
|
||||||
|
@ -42,11 +42,7 @@ routine_urlpatterns = [
|
||||||
views.delete_skill_from_routine,
|
views.delete_skill_from_routine,
|
||||||
name="delete_skill_from_routine",
|
name="delete_skill_from_routine",
|
||||||
),
|
),
|
||||||
path(
|
path(r"suggest/", views.suggest_routine, name="suggest_routine",),
|
||||||
r"suggest/",
|
|
||||||
views.suggest_routine,
|
|
||||||
name="suggest_routine",
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Chrono
|
# Chrono
|
|
@ -1,26 +1,24 @@
|
||||||
# coding=UTF-8
|
|
||||||
|
|
||||||
from django.db.models import Q
|
from datetime import datetime
|
||||||
from django.shortcuts import render, get_object_or_404
|
import math
|
||||||
from django.template import RequestContext
|
import random
|
||||||
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
|
|
||||||
|
|
||||||
import simplejson
|
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 .models import Skill, Educative, Routine, Chrono, RoutineSkill
|
||||||
from .forms import RoutineForm, ChronoForm
|
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):
|
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
|
:param lookup_class: classe fille dans laquelle la recherche doit être
|
||||||
faite.
|
faite.
|
||||||
:type lookup_class: string (`skill` ou `routine`).
|
:type lookup_class: string (`skill` ou `routine`).ùpdem
|
||||||
:param lookup_value: pattern de recherche.
|
:param lookup_value: pattern de recherche.
|
||||||
:type lookup_value: string.
|
:type lookup_value: string.
|
||||||
|
|
||||||
|
@ -261,11 +259,11 @@ def routine_details(request, routineid):
|
||||||
if not skill_link.skill.is_competitive:
|
if not skill_link.skill.is_competitive:
|
||||||
is_competitive = False
|
is_competitive = False
|
||||||
|
|
||||||
if skill_link.skill.ageBoy is not None and skill_link.skill.ageBoy > age_boy:
|
if skill_link.skill.age_boy is not None and skill_link.skill.age_boy > age_boy:
|
||||||
age_boy = skill_link.skill.ageBoy
|
age_boy = skill_link.skill.age_boy
|
||||||
|
|
||||||
if skill_link.skill.ageGirl is not None and skill_link.skill.ageGirl > age_girl:
|
if skill_link.skill.age_girl is not None and skill_link.skill.age_girl > age_girl:
|
||||||
age_girl = skill_link.skill.ageGirl
|
age_girl = skill_link.skill.age_girl
|
||||||
|
|
||||||
if routine.skill_links.all().count() != 10:
|
if routine.skill_links.all().count() != 10:
|
||||||
is_competitive = False
|
is_competitive = False
|
||||||
|
@ -278,11 +276,11 @@ def routine_details(request, routineid):
|
||||||
if routine.rank is None or routine.rank < rank:
|
if routine.rank is None or routine.rank < rank:
|
||||||
routine.rank = rank
|
routine.rank = rank
|
||||||
|
|
||||||
if routine.ageBoy is None or routine.ageBoy < age_boy:
|
if routine.age_boy is None or routine.age_boy < age_boy:
|
||||||
routine.ageBoy = age_boy
|
routine.age_boy = age_boy
|
||||||
|
|
||||||
if routine.ageGirl is None or routine.ageGirl < age_girl:
|
if routine.age_girl is None or routine.age_girl < age_girl:
|
||||||
routine.ageGirl = age_girl
|
routine.age_girl = age_girl
|
||||||
|
|
||||||
routine.is_competitive = is_competitive
|
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()
|
number_of_skill = skillid_list.count()
|
||||||
selected_skillid_list = [
|
selected_skillid_list = [
|
||||||
skillid_list[x]["id"]
|
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)
|
skill_list = Skill.objects.filter(id__in=selected_skillid_list)
|
||||||
|
@ -387,12 +387,14 @@ def __construct_routine(
|
||||||
|
|
||||||
if current_routine:
|
if current_routine:
|
||||||
skill_list = Skill.objects.filter(
|
skill_list = Skill.objects.filter(
|
||||||
departure = current_routine[-1].landing
|
departure=current_routine[-1].landing
|
||||||
) # , difficulty__lte = total_difficulty_score
|
) # , difficulty__lte = total_difficulty_score
|
||||||
if len(current_routine) == (max_routine_length - 1):
|
if len(current_routine) == (max_routine_length - 1):
|
||||||
skill_list = skill_list.filter(landing__longLabel="Debout")
|
skill_list = skill_list.filter(landing__longLabel="Debout")
|
||||||
if logic and current_routine[-1].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:
|
else:
|
||||||
skill_list = Skill.objects.filter(departure__longLabel="Debout")
|
skill_list = Skill.objects.filter(departure__longLabel="Debout")
|
||||||
|
|
||||||
|
@ -404,23 +406,31 @@ def __construct_routine(
|
||||||
min_diff_skill = total_difficulty_score
|
min_diff_skill = total_difficulty_score
|
||||||
max_diff_skill = total_difficulty_score + 3
|
max_diff_skill = total_difficulty_score + 3
|
||||||
else:
|
else:
|
||||||
if math.ceil(total_difficulty_score / max_routine_length) <= max_skill_difficulty:
|
if (
|
||||||
min_diff_skill = math.ceil(max((total_difficulty_score / max_routine_length) - 5, 0))
|
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:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
if (math.ceil(total_difficulty_score / max_routine_length) + 2) <= max_skill_difficulty:
|
if (
|
||||||
max_diff_skill = math.ceil(total_difficulty_score / max_routine_length) + 2
|
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:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
skill_list = skill_list.filter(
|
skill_list = skill_list.filter(
|
||||||
difficulty__gte = (min_diff_skill / 10),
|
difficulty__gte=(min_diff_skill / 10), difficulty__lte=(max_diff_skill / 10)
|
||||||
difficulty__lte = (max_diff_skill / 10)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if gymnast:
|
if gymnast:
|
||||||
skill_list = skill_list.filter(cando__gymnast = gymnast)
|
skill_list = skill_list.filter(cando__gymnast=gymnast)
|
||||||
|
|
||||||
for skill in skill_list:
|
for skill in skill_list:
|
||||||
current_routine.append(skill)
|
current_routine.append(skill)
|
||||||
|
@ -429,7 +439,9 @@ def __construct_routine(
|
||||||
current_routine,
|
current_routine,
|
||||||
max_routine_length,
|
max_routine_length,
|
||||||
max_skill_difficulty,
|
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,
|
competition,
|
||||||
logic,
|
logic,
|
||||||
gymnast,
|
gymnast,
|
||||||
|
@ -442,7 +454,7 @@ def __construct_routine(
|
||||||
|
|
||||||
def suggest_routine(
|
def suggest_routine(
|
||||||
request,
|
request,
|
||||||
max_routine_length = 2,
|
max_routine_length=2,
|
||||||
total_difficulty_score=None,
|
total_difficulty_score=None,
|
||||||
competition=True,
|
competition=True,
|
||||||
logic=True,
|
logic=True,
|
||||||
|
@ -471,24 +483,32 @@ def suggest_routine(
|
||||||
total_difficulty_score = 26
|
total_difficulty_score = 26
|
||||||
|
|
||||||
if gymnast:
|
if gymnast:
|
||||||
max_skill_difficulty = Educative.objects.values('difficulty').filter(cando__gymnast=gymnast).order_by(
|
max_skill_difficulty = (
|
||||||
"-difficulty"
|
Educative.objects.values("difficulty")
|
||||||
)[:1][0]["difficulty"] * 10
|
.filter(cando__gymnast=gymnast)
|
||||||
|
.order_by("-difficulty")[:1][0]["difficulty"]
|
||||||
|
* 10
|
||||||
|
)
|
||||||
else:
|
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)
|
# difficulty_scores = range(5, 45, 5)
|
||||||
# for total_difficulty_score in difficulty_scores:
|
# for total_difficulty_score in difficulty_scores:
|
||||||
# print("===============================================================================================")
|
# print("===============================================================================================")
|
||||||
__construct_routine(
|
__construct_routine(
|
||||||
routine,
|
routine,
|
||||||
max_routine_length,
|
max_routine_length,
|
||||||
max_skill_difficulty,
|
max_skill_difficulty,
|
||||||
total_difficulty_score,
|
total_difficulty_score,
|
||||||
competition,
|
competition,
|
||||||
logic,
|
logic,
|
||||||
gymnast,
|
gymnast,
|
||||||
)
|
)
|
||||||
# print(routines)
|
# 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