Create models
This commit is contained in:
parent
8cde47bab7
commit
6a3390bb8d
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MemberConfig(AppConfig):
|
||||
name = 'apps.member'
|
|
@ -0,0 +1,219 @@
|
|||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from polymorphic.models import PolymorphicModel
|
||||
|
||||
from tournament.models import Team, Tournament
|
||||
|
||||
|
||||
class TFJMUser(AbstractUser):
|
||||
USERNAME_FIELD = 'email'
|
||||
REQUIRED_FIELDS = []
|
||||
|
||||
email = models.EmailField(
|
||||
unique=True,
|
||||
verbose_name=_("email"),
|
||||
)
|
||||
|
||||
team = models.ForeignKey(
|
||||
Team,
|
||||
null=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="users",
|
||||
verbose_name=_("team"),
|
||||
)
|
||||
|
||||
birth_date = models.DateField(
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("birth date"),
|
||||
)
|
||||
|
||||
gender = models.CharField(
|
||||
max_length=16,
|
||||
null=True,
|
||||
default=None,
|
||||
choices=[
|
||||
("male", _("Male")),
|
||||
("female", _("Female")),
|
||||
("non-binary", _("Non binary")),
|
||||
],
|
||||
verbose_name=_("addresss"),
|
||||
)
|
||||
|
||||
address = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("address"),
|
||||
)
|
||||
|
||||
postal_code = models.PositiveSmallIntegerField(
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("postal code"),
|
||||
)
|
||||
|
||||
city = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("city"),
|
||||
)
|
||||
|
||||
country = models.CharField(
|
||||
max_length=255,
|
||||
default="France",
|
||||
null=True,
|
||||
verbose_name=_("country"),
|
||||
)
|
||||
|
||||
phone_number = models.CharField(
|
||||
max_length=20,
|
||||
null=True,
|
||||
blank=True,
|
||||
default=None,
|
||||
verbose_name=_("phone number"),
|
||||
)
|
||||
|
||||
school = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("school"),
|
||||
)
|
||||
|
||||
student_class = models.CharField(
|
||||
max_length=16,
|
||||
choices=[
|
||||
('seconde', _("Seconde or less")),
|
||||
('première', _("Première")),
|
||||
('terminale', _("Terminale")),
|
||||
],
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name="class",
|
||||
)
|
||||
|
||||
responsible_name = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("responsible name"),
|
||||
)
|
||||
|
||||
responsible_phone = models.CharField(
|
||||
max_length=20,
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("responsible phone"),
|
||||
)
|
||||
|
||||
responsible_email = models.EmailField(
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("responsible email"),
|
||||
)
|
||||
|
||||
description = models.TextField(
|
||||
null=True,
|
||||
default=None,
|
||||
verbose_name=_("description"),
|
||||
)
|
||||
|
||||
role = models.CharField(
|
||||
max_length=16,
|
||||
choices=[
|
||||
("admin", _("admin")),
|
||||
("organizer", _("organizer")),
|
||||
("encadrant", _("encadrant")),
|
||||
("participant", _("participant")),
|
||||
]
|
||||
)
|
||||
|
||||
year = models.PositiveIntegerField(
|
||||
verbose_name=_("year"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("user")
|
||||
verbose_name_plural = _("users")
|
||||
|
||||
|
||||
class AbstractDocument(PolymorphicModel):
|
||||
file = models.FileField(
|
||||
unique=True,
|
||||
upload_to="files/",
|
||||
verbose_name=_("file"),
|
||||
)
|
||||
|
||||
team = models.ForeignKey(
|
||||
Team,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="documents",
|
||||
verbose_name=_("team"),
|
||||
)
|
||||
|
||||
tournament = models.ForeignKey(
|
||||
Tournament,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="documents",
|
||||
verbose_name=_("tournament"),
|
||||
)
|
||||
|
||||
type = models.CharField(
|
||||
max_length=32,
|
||||
choices=[
|
||||
("parental_consent", _("Parental consent")),
|
||||
("photo_consent", _("Photo consent")),
|
||||
("sanitary_plug", _("Sanitary plug")),
|
||||
("motivation_letter", _("Motivation letter")),
|
||||
("scholarship", _("Scholarship")),
|
||||
("solution", _("Solution")),
|
||||
("synthesis", _("Synthesis")),
|
||||
],
|
||||
verbose_name=_("type"),
|
||||
)
|
||||
|
||||
uploaded_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name=_("uploaded at"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("abstract document")
|
||||
verbose_name_plural = _("abstract documents")
|
||||
|
||||
|
||||
class Document(AbstractDocument):
|
||||
class Meta:
|
||||
verbose_name = _("document")
|
||||
verbose_name_plural = _("documents")
|
||||
|
||||
|
||||
class Solution(Document):
|
||||
problem = models.PositiveSmallIntegerField(
|
||||
verbose_name=_("problem"),
|
||||
)
|
||||
|
||||
def save(self, **kwargs):
|
||||
self.type = "solution"
|
||||
super().save(**kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("solution")
|
||||
verbose_name_plural = _("solutions")
|
||||
|
||||
|
||||
class Synthesis(Document):
|
||||
problem = models.PositiveSmallIntegerField(
|
||||
verbose_name=_("problem"),
|
||||
)
|
||||
|
||||
def save(self, **kwargs):
|
||||
self.type = "synthesis"
|
||||
super().save(**kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("synthesis")
|
||||
verbose_name_plural = _("syntheses")
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
|
@ -0,0 +1,5 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class TournamentConfig(AppConfig):
|
||||
name = 'apps.tournament'
|
|
@ -0,0 +1,171 @@
|
|||
import os
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class Tournament(models.Model):
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("name"),
|
||||
)
|
||||
|
||||
organizers = models.ManyToManyField(
|
||||
'member.TFJMUser',
|
||||
related_name="organized_tournaments",
|
||||
verbose_name=_("organizers"),
|
||||
)
|
||||
|
||||
size = models.PositiveSmallIntegerField(
|
||||
verbose_name=_("size"),
|
||||
)
|
||||
|
||||
place = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("place"),
|
||||
)
|
||||
|
||||
price = models.PositiveSmallIntegerField(
|
||||
verbose_name=_("price"),
|
||||
)
|
||||
|
||||
description = models.TextField(
|
||||
verbose_name=_("description"),
|
||||
)
|
||||
|
||||
date_start = models.DateField(
|
||||
verbose_name=_("date start"),
|
||||
)
|
||||
|
||||
date_end = models.DateField(
|
||||
verbose_name=_("date start"),
|
||||
)
|
||||
|
||||
date_inscription = models.DateTimeField(
|
||||
verbose_name=_("date of registration closing"),
|
||||
)
|
||||
|
||||
date_solutions = models.DateTimeField(
|
||||
verbose_name=_("date of maximal solution submission"),
|
||||
)
|
||||
|
||||
date_syntheses = models.DateTimeField(
|
||||
verbose_name=_("date of maximal syntheses submission"),
|
||||
)
|
||||
|
||||
final = models.BooleanField(
|
||||
verbose_name=_("final tournament"),
|
||||
)
|
||||
|
||||
year = models.PositiveIntegerField(
|
||||
verbose_name=_("year")
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_final(cls):
|
||||
return cls.objects.get(year=os.getenv("TFJM_YEAR"), final=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("tournament")
|
||||
verbose_name_plural = _("tournaments")
|
||||
|
||||
|
||||
class Team(models.Model):
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("name"),
|
||||
)
|
||||
|
||||
trigram = models.CharField(
|
||||
max_length=3,
|
||||
verbose_name=_("trigram"),
|
||||
)
|
||||
|
||||
tournament = models.ForeignKey(
|
||||
Tournament,
|
||||
on_delete=models.PROTECT,
|
||||
verbose_name=_("tournament"),
|
||||
)
|
||||
|
||||
inscription_date = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name=_("inscription date"),
|
||||
)
|
||||
|
||||
validation_status = models.CharField(
|
||||
max_length=8,
|
||||
choices=[
|
||||
("invalid", _("Registration not validated")),
|
||||
("waiting", _("Waiting for validation")),
|
||||
("valid", _("Registration validated")),
|
||||
],
|
||||
verbose_name=_("validation status"),
|
||||
)
|
||||
|
||||
selected_for_final = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name=_("selected for final"),
|
||||
)
|
||||
|
||||
access_code = models.CharField(
|
||||
max_length=6,
|
||||
unique=True,
|
||||
verbose_name=_("access code"),
|
||||
)
|
||||
|
||||
year = models.PositiveIntegerField(
|
||||
verbose_name=_("year"),
|
||||
)
|
||||
|
||||
@property
|
||||
def encadrants(self):
|
||||
return self.users.filter(role="encadrant")
|
||||
|
||||
@property
|
||||
def participants(self):
|
||||
return self.users.filter(role="participant")
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("team")
|
||||
verbose_name_plural = _("teams")
|
||||
unique_together = (('name', 'year',), ('trigram', 'year',),)
|
||||
|
||||
|
||||
class Payment(models.Model):
|
||||
user = models.OneToOneField(
|
||||
'member.TFJMUser',
|
||||
on_delete=models.CASCADE,
|
||||
related_name="payment",
|
||||
verbose_name=_("user"),
|
||||
)
|
||||
|
||||
team = models.ForeignKey(
|
||||
Team,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="payments",
|
||||
verbose_name=_("team"),
|
||||
)
|
||||
|
||||
method = models.CharField(
|
||||
max_length=16,
|
||||
choices=[
|
||||
("not_paid", _("Not paid")),
|
||||
("credit_card", _("Credit card")),
|
||||
("check", _("Bank check")),
|
||||
("transfer", _("Bank transfer")),
|
||||
("cash", _("Cash")),
|
||||
("scholarship", _("Scholarship")),
|
||||
],
|
||||
default="not_paid",
|
||||
verbose_name=_("payment method"),
|
||||
)
|
||||
|
||||
validation_status = models.CharField(
|
||||
max_length=8,
|
||||
choices=[
|
||||
("invalid", _("Registration not validated")),
|
||||
("waiting", _("Waiting for validation")),
|
||||
("valid", _("Registration validated")),
|
||||
],
|
||||
verbose_name=_("validation status"),
|
||||
)
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,3 @@
|
|||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
|
@ -6,7 +6,7 @@ django-allauth==0.39.1
|
|||
django-crispy-forms==1.7.2
|
||||
django-extensions==2.1.9
|
||||
django-filter==2.2.0
|
||||
django-polymorphic==2.0.3
|
||||
django-polymorphic==2.1.2
|
||||
django-tables2==2.1.0
|
||||
docutils==0.14
|
||||
idna==2.8
|
||||
|
|
|
@ -11,9 +11,13 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
|
|||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||
APPS_DIR = os.path.realpath(os.path.join(BASE_DIR, "apps"))
|
||||
sys.path.append(APPS_DIR)
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
|
@ -37,6 +41,9 @@ INSTALLED_APPS = [
|
|||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
'member',
|
||||
'tournament',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -100,6 +107,8 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
},
|
||||
]
|
||||
|
||||
AUTH_USER_MODEL = 'member.TFJMUser'
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||
|
|
Loading…
Reference in New Issue