mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-28 23:43:22 +00:00
refactor: Utilisation d'une application "Common" pour tous les modèles
de référence
This commit is contained in:
@ -4,3 +4,6 @@ from django.apps import AppConfig
|
|||||||
class CommonConfig(AppConfig):
|
class CommonConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'Common'
|
name = 'Common'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
import Common.signals
|
||||||
@ -1,13 +1,59 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
class StudentCompetency(models.Model):
|
class Domain(models.Model):
|
||||||
student = models.ForeignKey('Subscriptions.Student', on_delete=models.CASCADE, related_name='competency_scores')
|
name = models.CharField(max_length=255)
|
||||||
competency = models.ForeignKey('School.Competency', on_delete=models.CASCADE, related_name='student_scores')
|
cycle = models.IntegerField(choices=[(1, 'Cycle 1'), (2, 'Cycle 2'), (3, 'Cycle 3'), (4, 'Cycle 4')])
|
||||||
score = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
|
|
||||||
comment = models.TextField(blank=True, null=True)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
unique_together = ('student', 'competency')
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.student} - {self.competency.name} - Score: {self.score}"
|
return f"{self.name} (Cycle {self.cycle})"
|
||||||
|
|
||||||
|
class Category(models.Model):
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
domain = models.ForeignKey(Domain, on_delete=models.CASCADE, related_name='categories')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Competency(models.Model):
|
||||||
|
name = models.TextField()
|
||||||
|
end_of_cycle = models.BooleanField(default=False, null=True, blank=True)
|
||||||
|
level = models.CharField(max_length=50, null=True, blank=True)
|
||||||
|
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='competencies')
|
||||||
|
|
||||||
|
establishments = models.ManyToManyField(
|
||||||
|
'Establishment.Establishment',
|
||||||
|
through='School.EstablishmentCompetency',
|
||||||
|
related_name='competencies',
|
||||||
|
blank=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class PaymentPlanType(models.Model):
|
||||||
|
code = models.CharField(max_length=50, unique=True)
|
||||||
|
label = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.label
|
||||||
|
|
||||||
|
class PaymentModeType(models.Model):
|
||||||
|
code = models.CharField(max_length=50, unique=True)
|
||||||
|
label = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.label
|
||||||
|
|
||||||
|
class Cycle(models.Model):
|
||||||
|
number = models.IntegerField(unique=True)
|
||||||
|
label = models.CharField(max_length=50)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Cycle {self.number} - {self.label}"
|
||||||
|
|
||||||
|
class Level(models.Model):
|
||||||
|
name = models.CharField(max_length=50)
|
||||||
|
cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name='levels')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
21
Back-End/Common/serializers.py
Normal file
21
Back-End/Common/serializers.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
from Common.models import (
|
||||||
|
Domain,
|
||||||
|
Category,
|
||||||
|
Competency
|
||||||
|
)
|
||||||
|
|
||||||
|
class DomainSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Domain
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class CategorySerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Category
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class CompetencySerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Competency
|
||||||
|
fields = '__all__'
|
||||||
@ -2,10 +2,10 @@ import json
|
|||||||
import os
|
import os
|
||||||
from django.db.models.signals import post_migrate
|
from django.db.models.signals import post_migrate
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from School.models import Domain, Category, Competency, PaymentModeType, PaymentPlanType
|
from Common.models import Domain, Category, Competency, PaymentModeType, PaymentPlanType, Cycle, Level
|
||||||
|
|
||||||
@receiver(post_migrate)
|
@receiver(post_migrate)
|
||||||
def school_post_migrate(sender, **kwargs):
|
def common_post_migrate(sender, **kwargs):
|
||||||
if sender.name != "School":
|
if sender.name != "School":
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -57,7 +57,6 @@ def school_post_migrate(sender, **kwargs):
|
|||||||
for mode in payment_mode_types:
|
for mode in payment_mode_types:
|
||||||
PaymentModeType.objects.get_or_create(code=mode["code"], defaults={"label": mode["label"]})
|
PaymentModeType.objects.get_or_create(code=mode["code"], defaults={"label": mode["label"]})
|
||||||
|
|
||||||
# ... après la création des PaymentModeType ...
|
|
||||||
payment_plan_types = [
|
payment_plan_types = [
|
||||||
{"code": "ONE_TIME", "label": "1 fois"},
|
{"code": "ONE_TIME", "label": "1 fois"},
|
||||||
{"code": "THREE_TIMES", "label": "3 fois"},
|
{"code": "THREE_TIMES", "label": "3 fois"},
|
||||||
@ -65,4 +64,34 @@ def school_post_migrate(sender, **kwargs):
|
|||||||
{"code": "TWELVE_TIMES", "label": "12 fois"},
|
{"code": "TWELVE_TIMES", "label": "12 fois"},
|
||||||
]
|
]
|
||||||
for plan in payment_plan_types:
|
for plan in payment_plan_types:
|
||||||
PaymentPlanType.objects.get_or_create(code=plan["code"], defaults={"label": plan["label"]})
|
PaymentPlanType.objects.get_or_create(code=plan["code"], defaults={"label": plan["label"]})
|
||||||
|
|
||||||
|
# Création des cycles
|
||||||
|
cycles_data = [
|
||||||
|
{"number": 1, "label": "Cycle 1"},
|
||||||
|
{"number": 2, "label": "Cycle 2"},
|
||||||
|
{"number": 3, "label": "Cycle 3"},
|
||||||
|
{"number": 4, "label": "Cycle 4"},
|
||||||
|
]
|
||||||
|
cycle_objs = {}
|
||||||
|
for cycle in cycles_data:
|
||||||
|
obj, _ = Cycle.objects.get_or_create(number=cycle["number"], defaults={"label": cycle["label"]})
|
||||||
|
cycle_objs[cycle["number"]] = obj
|
||||||
|
|
||||||
|
# Création des niveaux et association au cycle
|
||||||
|
levels_data = [
|
||||||
|
{"name": "TPS", "cycle": 1},
|
||||||
|
{"name": "PS", "cycle": 1},
|
||||||
|
{"name": "MS", "cycle": 1},
|
||||||
|
{"name": "GS", "cycle": 1},
|
||||||
|
{"name": "CP", "cycle": 2},
|
||||||
|
{"name": "CE1", "cycle": 2},
|
||||||
|
{"name": "CE2", "cycle": 2},
|
||||||
|
{"name": "CM1", "cycle": 3},
|
||||||
|
{"name": "CM2", "cycle": 3},
|
||||||
|
]
|
||||||
|
for level in levels_data:
|
||||||
|
Level.objects.get_or_create(
|
||||||
|
name=level["name"],
|
||||||
|
defaults={"cycle": cycle_objs[level["cycle"]]}
|
||||||
|
)
|
||||||
18
Back-End/Common/urls.py
Normal file
18
Back-End/Common/urls.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from django.urls import path, re_path
|
||||||
|
|
||||||
|
from .views import (
|
||||||
|
DomainListCreateView, DomainDetailView,
|
||||||
|
CategoryListCreateView, CategoryDetailView,
|
||||||
|
CompetencyListCreateView, CompetencyDetailView,
|
||||||
|
)
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
re_path(r'^domains$', DomainListCreateView.as_view(), name="domain_list_create"),
|
||||||
|
re_path(r'^domains/(?P<id>[0-9]+)$', DomainDetailView.as_view(), name="domain_detail"),
|
||||||
|
|
||||||
|
re_path(r'^categories$', CategoryListCreateView.as_view(), name="category_list_create"),
|
||||||
|
re_path(r'^categories/(?P<id>[0-9]+)$', CategoryDetailView.as_view(), name="category_detail"),
|
||||||
|
|
||||||
|
re_path(r'^competencies$', CompetencyListCreateView.as_view(), name="competency_list_create"),
|
||||||
|
re_path(r'^competencies/(?P<id>[0-9]+)$', CompetencyDetailView.as_view(), name="competency_detail"),
|
||||||
|
]
|
||||||
@ -1,3 +1,165 @@
|
|||||||
from django.shortcuts import render
|
from django.http.response import JsonResponse
|
||||||
|
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from rest_framework.parsers import JSONParser
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from .models import (
|
||||||
|
Domain,
|
||||||
|
Category,
|
||||||
|
Competency
|
||||||
|
)
|
||||||
|
from .serializers import (
|
||||||
|
DomainSerializer,
|
||||||
|
CategorySerializer,
|
||||||
|
CompetencySerializer
|
||||||
|
)
|
||||||
|
|
||||||
# Create your views here.
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class DomainListCreateView(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
domains = Domain.objects.all()
|
||||||
|
serializer = DomainSerializer(domains, many=True)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = DomainSerializer(data=data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class DomainDetailView(APIView):
|
||||||
|
def get(self, request, id):
|
||||||
|
try:
|
||||||
|
domain = Domain.objects.get(id=id)
|
||||||
|
serializer = DomainSerializer(domain)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
except Domain.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
def put(self, request, id):
|
||||||
|
try:
|
||||||
|
domain = Domain.objects.get(id=id)
|
||||||
|
except Domain.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = DomainSerializer(domain, data=data, partial=True)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def delete(self, request, id):
|
||||||
|
try:
|
||||||
|
domain = Domain.objects.get(id=id)
|
||||||
|
domain.delete()
|
||||||
|
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||||
|
except Domain.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
# Répète la même logique pour Category, Competency, EstablishmentCompetency
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class CategoryListCreateView(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
categories = Category.objects.all()
|
||||||
|
serializer = CategorySerializer(categories, many=True)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = CategorySerializer(data=data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class CategoryDetailView(APIView):
|
||||||
|
def get(self, request, id):
|
||||||
|
try:
|
||||||
|
category = Category.objects.get(id=id)
|
||||||
|
serializer = CategorySerializer(category)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
except Category.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
def put(self, request, id):
|
||||||
|
try:
|
||||||
|
category = Category.objects.get(id=id)
|
||||||
|
except Category.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = CategorySerializer(category, data=data, partial=True)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def delete(self, request, id):
|
||||||
|
try:
|
||||||
|
category = Category.objects.get(id=id)
|
||||||
|
category.delete()
|
||||||
|
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||||
|
except Category.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class CompetencyListCreateView(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
cycle = request.GET.get('cycle')
|
||||||
|
if cycle is None:
|
||||||
|
return JsonResponse({'error': 'cycle est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
competencies_list = getAllObjects(Competency)
|
||||||
|
competencies_list = competencies_list.filter(
|
||||||
|
category__domain__cycle=cycle
|
||||||
|
).distinct()
|
||||||
|
serializer = CompetencySerializer(competencies_list, many=True)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = CompetencySerializer(data=data)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class CompetencyDetailView(APIView):
|
||||||
|
def get(self, request, id):
|
||||||
|
try:
|
||||||
|
competency = Competency.objects.get(id=id)
|
||||||
|
serializer = CompetencySerializer(competency)
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
except Competency.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
def put(self, request, id):
|
||||||
|
try:
|
||||||
|
competency = Competency.objects.get(id=id)
|
||||||
|
except Competency.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
data = JSONParser().parse(request)
|
||||||
|
serializer = CompetencySerializer(competency, data=data, partial=True)
|
||||||
|
if serializer.is_valid():
|
||||||
|
serializer.save()
|
||||||
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def delete(self, request, id):
|
||||||
|
try:
|
||||||
|
competency = Competency.objects.get(id=id)
|
||||||
|
competency.delete()
|
||||||
|
return JsonResponse({'message': 'Deleted'}, safe=False)
|
||||||
|
except Competency.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|||||||
@ -7,7 +7,8 @@ from rest_framework import status
|
|||||||
from .models import Establishment
|
from .models import Establishment
|
||||||
from .serializers import EstablishmentSerializer
|
from .serializers import EstablishmentSerializer
|
||||||
from N3wtSchool.bdd import delete_object, getAllObjects
|
from N3wtSchool.bdd import delete_object, getAllObjects
|
||||||
from School.models import Competency, EstablishmentCompetency
|
from School.models import EstablishmentCompetency
|
||||||
|
from Common.models import Competency
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
|||||||
@ -42,6 +42,7 @@ ALLOWED_HOSTS = ['*']
|
|||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'Common.apps.CommonConfig',
|
||||||
'Subscriptions.apps.GestioninscriptionsConfig',
|
'Subscriptions.apps.GestioninscriptionsConfig',
|
||||||
'Auth.apps.GestionloginConfig',
|
'Auth.apps.GestionloginConfig',
|
||||||
'GestionMessagerie.apps.GestionMessagerieConfig',
|
'GestionMessagerie.apps.GestionMessagerieConfig',
|
||||||
|
|||||||
@ -39,6 +39,7 @@ schema_view = get_schema_view(
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path("Common/", include(("Common.urls", 'Common'), namespace='Common')),
|
||||||
path("Subscriptions/", include(("Subscriptions.urls", 'Subscriptions'), namespace='Subscriptions')),
|
path("Subscriptions/", include(("Subscriptions.urls", 'Subscriptions'), namespace='Subscriptions')),
|
||||||
path("Auth/", include(("Auth.urls", 'Auth'), namespace='Auth')),
|
path("Auth/", include(("Auth.urls", 'Auth'), namespace='Auth')),
|
||||||
path("GestionMessagerie/", include(("GestionMessagerie.urls", 'GestionMessagerie'), namespace='GestionMessagerie')),
|
path("GestionMessagerie/", include(("GestionMessagerie.urls", 'GestionMessagerie'), namespace='GestionMessagerie')),
|
||||||
|
|||||||
@ -2,7 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
class SchoolConfig(AppConfig):
|
class SchoolConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'School'
|
name = 'School'
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
import School.signals
|
|
||||||
@ -4,12 +4,15 @@ from Subscriptions.models import (
|
|||||||
RegistrationFileGroup
|
RegistrationFileGroup
|
||||||
)
|
)
|
||||||
from Auth.models import Profile, ProfileRole
|
from Auth.models import Profile, ProfileRole
|
||||||
|
from Common.models import (
|
||||||
|
PaymentModeType,
|
||||||
|
PaymentPlanType,
|
||||||
|
Level
|
||||||
|
)
|
||||||
from School.models import (
|
from School.models import (
|
||||||
FeeType,
|
FeeType,
|
||||||
Speciality,
|
Speciality,
|
||||||
Teacher,
|
Teacher,
|
||||||
PaymentModeType,
|
|
||||||
PaymentPlanType,
|
|
||||||
DiscountType,
|
DiscountType,
|
||||||
Fee,
|
Fee,
|
||||||
Discount,
|
Discount,
|
||||||
@ -280,6 +283,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def init_school_classes(self):
|
def init_school_classes(self):
|
||||||
school_classes_data = self.load_data('school_classes.json')
|
school_classes_data = self.load_data('school_classes.json')
|
||||||
|
levels = list(Level.objects.all())
|
||||||
|
|
||||||
for index, class_data in enumerate(school_classes_data, start=1):
|
for index, class_data in enumerate(school_classes_data, start=1):
|
||||||
# Randomize establishment
|
# Randomize establishment
|
||||||
@ -288,7 +292,7 @@ class Command(BaseCommand):
|
|||||||
class_data["establishment"] = establishment.id
|
class_data["establishment"] = establishment.id
|
||||||
|
|
||||||
# Randomize levels
|
# Randomize levels
|
||||||
class_data["levels"] = random.sample(range(1, 10), random.randint(1, 5))
|
class_data["levels"] = [level.id for level in random.sample(levels, random.randint(1, min(5, len(levels))))]
|
||||||
|
|
||||||
# Randomize teachers
|
# Randomize teachers
|
||||||
establishment_teachers = list(Teacher.objects.filter(profile_role__establishment=establishment))
|
establishment_teachers = list(Teacher.objects.filter(profile_role__establishment=establishment))
|
||||||
@ -331,6 +335,7 @@ class Command(BaseCommand):
|
|||||||
fake = Faker('fr_FR') # Utiliser le locale français pour Faker
|
fake = Faker('fr_FR') # Utiliser le locale français pour Faker
|
||||||
|
|
||||||
file_group_count = RegistrationFileGroup.objects.count()
|
file_group_count = RegistrationFileGroup.objects.count()
|
||||||
|
levels = list(Level.objects.all())
|
||||||
|
|
||||||
# Récupérer tous les profils existants avec un ProfileRole Parent
|
# Récupérer tous les profils existants avec un ProfileRole Parent
|
||||||
profiles_with_parent_role = Profile.objects.filter(roles__role_type=ProfileRole.RoleType.PROFIL_PARENT).distinct()
|
profiles_with_parent_role = Profile.objects.filter(roles__role_type=ProfileRole.RoleType.PROFIL_PARENT).distinct()
|
||||||
@ -376,7 +381,7 @@ class Command(BaseCommand):
|
|||||||
"birth_postal_code": fake.postcode(),
|
"birth_postal_code": fake.postcode(),
|
||||||
"nationality": fake.country(),
|
"nationality": fake.country(),
|
||||||
"attending_physician": fake.name(),
|
"attending_physician": fake.name(),
|
||||||
"level": fake.random_int(min=1, max=6),
|
"level": random.choice(levels).id,
|
||||||
"guardians": [guardian_data],
|
"guardians": [guardian_data],
|
||||||
"sibling": []
|
"sibling": []
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,7 +50,7 @@ class SchoolClass(models.Model):
|
|||||||
school_year = models.CharField(max_length=9, blank=True)
|
school_year = models.CharField(max_length=9, blank=True)
|
||||||
updated_date = models.DateTimeField(auto_now=True)
|
updated_date = models.DateTimeField(auto_now=True)
|
||||||
teachers = models.ManyToManyField(Teacher, blank=True)
|
teachers = models.ManyToManyField(Teacher, blank=True)
|
||||||
levels = ArrayField(models.IntegerField(choices=LEVEL_CHOICES), default=list)
|
levels = models.ManyToManyField('Common.Level', blank=True, related_name='school_classes')
|
||||||
type = models.IntegerField(choices=PLANNING_TYPE_CHOICES, default=1)
|
type = models.IntegerField(choices=PLANNING_TYPE_CHOICES, default=1)
|
||||||
time_range = models.JSONField(default=list)
|
time_range = models.JSONField(default=list)
|
||||||
opening_days = ArrayField(models.IntegerField(), default=list)
|
opening_days = ArrayField(models.IntegerField(), default=list)
|
||||||
@ -75,21 +75,6 @@ class FeeType(models.IntegerChoices):
|
|||||||
REGISTRATION_FEE = 0, 'Registration Fee'
|
REGISTRATION_FEE = 0, 'Registration Fee'
|
||||||
TUITION_FEE = 1, 'Tuition Fee'
|
TUITION_FEE = 1, 'Tuition Fee'
|
||||||
|
|
||||||
class PaymentPlanType(models.Model):
|
|
||||||
code = models.CharField(max_length=50, unique=True)
|
|
||||||
label = models.CharField(max_length=255)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.label
|
|
||||||
|
|
||||||
class PaymentModeType(models.Model):
|
|
||||||
code = models.CharField(max_length=50, unique=True)
|
|
||||||
label = models.CharField(max_length=255)
|
|
||||||
is_active = models.BooleanField(default=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.label
|
|
||||||
|
|
||||||
class Discount(models.Model):
|
class Discount(models.Model):
|
||||||
name = models.CharField(max_length=255, null=True, blank=True)
|
name = models.CharField(max_length=255, null=True, blank=True)
|
||||||
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
|
||||||
@ -115,7 +100,7 @@ class Fee(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class PaymentPlan(models.Model):
|
class PaymentPlan(models.Model):
|
||||||
plan_type = models.ForeignKey(PaymentPlanType, on_delete=models.PROTECT, related_name='payment_plans')
|
plan_type = models.ForeignKey('Common.PaymentPlanType', on_delete=models.PROTECT, related_name='payment_plans')
|
||||||
due_dates = ArrayField(models.DateField(), null=True, blank=True)
|
due_dates = ArrayField(models.DateField(), null=True, blank=True)
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_plans')
|
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_plans')
|
||||||
@ -124,45 +109,13 @@ class PaymentPlan(models.Model):
|
|||||||
return f"{self.plan_type.label} - {self.get_type_display()}"
|
return f"{self.plan_type.label} - {self.get_type_display()}"
|
||||||
|
|
||||||
class PaymentMode(models.Model):
|
class PaymentMode(models.Model):
|
||||||
mode = models.ForeignKey(PaymentModeType, on_delete=models.PROTECT, related_name='payment_modes')
|
mode = models.ForeignKey('Common.PaymentModeType', on_delete=models.PROTECT, related_name='payment_modes')
|
||||||
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
type = models.IntegerField(choices=FeeType.choices, default=FeeType.REGISTRATION_FEE)
|
||||||
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_modes')
|
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='payment_modes')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.mode.label} - {self.get_type_display()}"
|
return f"{self.mode.label} - {self.get_type_display()}"
|
||||||
|
|
||||||
class Domain(models.Model):
|
|
||||||
name = models.CharField(max_length=255)
|
|
||||||
cycle = models.IntegerField(choices=[(1, 'Cycle 1'), (2, 'Cycle 2'), (3, 'Cycle 3'), (4, 'Cycle 4')])
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return f"{self.name} (Cycle {self.cycle})"
|
|
||||||
|
|
||||||
|
|
||||||
class Category(models.Model):
|
|
||||||
name = models.CharField(max_length=255)
|
|
||||||
domain = models.ForeignKey(Domain, on_delete=models.CASCADE, related_name='categories')
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
|
|
||||||
class Competency(models.Model):
|
|
||||||
name = models.TextField()
|
|
||||||
end_of_cycle = models.BooleanField(default=False, null=True, blank=True)
|
|
||||||
level = models.CharField(max_length=50, null=True, blank=True)
|
|
||||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='competencies')
|
|
||||||
|
|
||||||
establishments = models.ManyToManyField(
|
|
||||||
'Establishment.Establishment',
|
|
||||||
through='EstablishmentCompetency',
|
|
||||||
related_name='competencies',
|
|
||||||
blank=True
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
class EstablishmentCompetency(models.Model):
|
class EstablishmentCompetency(models.Model):
|
||||||
"""
|
"""
|
||||||
Relation entre un établissement et une compétence.
|
Relation entre un établissement et une compétence.
|
||||||
@ -170,12 +123,12 @@ class EstablishmentCompetency(models.Model):
|
|||||||
"""
|
"""
|
||||||
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE)
|
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE)
|
||||||
competency = models.ForeignKey(
|
competency = models.ForeignKey(
|
||||||
Competency, on_delete=models.CASCADE, null=True, blank=True,
|
'Common.Competency', on_delete=models.CASCADE, null=True, blank=True,
|
||||||
help_text="Compétence de référence (optionnelle si custom)"
|
help_text="Compétence de référence (optionnelle si custom)"
|
||||||
)
|
)
|
||||||
custom_name = models.TextField(null=True, blank=True, help_text="Nom de la compétence custom")
|
custom_name = models.TextField(null=True, blank=True, help_text="Nom de la compétence custom")
|
||||||
custom_category = models.ForeignKey(
|
custom_category = models.ForeignKey(
|
||||||
Category, on_delete=models.CASCADE, null=True, blank=True,
|
'Common.Category', on_delete=models.CASCADE, null=True, blank=True,
|
||||||
help_text="Catégorie de la compétence custom"
|
help_text="Catégorie de la compétence custom"
|
||||||
)
|
)
|
||||||
is_required = models.BooleanField(default=True)
|
is_required = models.BooleanField(default=True)
|
||||||
|
|||||||
@ -9,9 +9,6 @@ from .models import (
|
|||||||
Fee,
|
Fee,
|
||||||
PaymentPlan,
|
PaymentPlan,
|
||||||
PaymentMode,
|
PaymentMode,
|
||||||
Domain,
|
|
||||||
Category,
|
|
||||||
Competency,
|
|
||||||
EstablishmentCompetency
|
EstablishmentCompetency
|
||||||
)
|
)
|
||||||
from Auth.models import Profile, ProfileRole
|
from Auth.models import Profile, ProfileRole
|
||||||
@ -22,21 +19,6 @@ from N3wtSchool import settings
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
class DomainSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Domain
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
class CategorySerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Category
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
class CompetencySerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Competency
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
class EstablishmentCompetencySerializer(serializers.ModelSerializer):
|
class EstablishmentCompetencySerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = EstablishmentCompetency
|
model = EstablishmentCompetency
|
||||||
@ -203,7 +185,6 @@ class SchoolClassSerializer(serializers.ModelSerializer):
|
|||||||
number_of_students=validated_data.get('number_of_students', 0),
|
number_of_students=validated_data.get('number_of_students', 0),
|
||||||
teaching_language=validated_data.get('teaching_language', ''),
|
teaching_language=validated_data.get('teaching_language', ''),
|
||||||
school_year=validated_data.get('school_year', ''),
|
school_year=validated_data.get('school_year', ''),
|
||||||
levels=levels_data,
|
|
||||||
type=validated_data.get('type', 1),
|
type=validated_data.get('type', 1),
|
||||||
time_range=validated_data.get('time_range', ['08:30', '17:30']),
|
time_range=validated_data.get('time_range', ['08:30', '17:30']),
|
||||||
opening_days=validated_data.get('opening_days', [1, 2, 4, 5]),
|
opening_days=validated_data.get('opening_days', [1, 2, 4, 5]),
|
||||||
@ -211,6 +192,7 @@ class SchoolClassSerializer(serializers.ModelSerializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
school_class.teachers.set(teachers_data)
|
school_class.teachers.set(teachers_data)
|
||||||
|
school_class.levels.set(levels_data)
|
||||||
|
|
||||||
for planning_data in plannings_data:
|
for planning_data in plannings_data:
|
||||||
Planning.objects.create(
|
Planning.objects.create(
|
||||||
@ -231,7 +213,6 @@ class SchoolClassSerializer(serializers.ModelSerializer):
|
|||||||
instance.number_of_students = validated_data.get('number_of_students', instance.number_of_students)
|
instance.number_of_students = validated_data.get('number_of_students', instance.number_of_students)
|
||||||
instance.teaching_language = validated_data.get('teaching_language', instance.teaching_language)
|
instance.teaching_language = validated_data.get('teaching_language', instance.teaching_language)
|
||||||
instance.school_year = validated_data.get('school_year', instance.school_year)
|
instance.school_year = validated_data.get('school_year', instance.school_year)
|
||||||
instance.levels = levels_data
|
|
||||||
instance.type = validated_data.get('type', instance.type)
|
instance.type = validated_data.get('type', instance.type)
|
||||||
instance.time_range = validated_data.get('time_range', instance.time_range)
|
instance.time_range = validated_data.get('time_range', instance.time_range)
|
||||||
instance.opening_days = validated_data.get('opening_days', instance.opening_days)
|
instance.opening_days = validated_data.get('opening_days', instance.opening_days)
|
||||||
@ -239,6 +220,7 @@ class SchoolClassSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
instance.save()
|
instance.save()
|
||||||
instance.teachers.set(teachers_data)
|
instance.teachers.set(teachers_data)
|
||||||
|
instance.levels.set(levels_data)
|
||||||
|
|
||||||
existing_plannings = {planning.level: planning for planning in instance.plannings.all()}
|
existing_plannings = {planning.level: planning for planning in instance.plannings.all()}
|
||||||
|
|
||||||
|
|||||||
@ -9,9 +9,6 @@ from .views import (
|
|||||||
DiscountListCreateView, DiscountDetailView,
|
DiscountListCreateView, DiscountDetailView,
|
||||||
PaymentPlanListCreateView, PaymentPlanDetailView,
|
PaymentPlanListCreateView, PaymentPlanDetailView,
|
||||||
PaymentModeListCreateView, PaymentModeDetailView,
|
PaymentModeListCreateView, PaymentModeDetailView,
|
||||||
DomainListCreateView, DomainDetailView,
|
|
||||||
CategoryListCreateView, CategoryDetailView,
|
|
||||||
CompetencyListCreateView, CompetencyDetailView,
|
|
||||||
EstablishmentCompetencyListCreateView, EstablishmentCompetencyDetailView,
|
EstablishmentCompetencyListCreateView, EstablishmentCompetencyDetailView,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,15 +37,6 @@ urlpatterns = [
|
|||||||
re_path(r'^paymentModes$', PaymentModeListCreateView.as_view(), name="payment_mode_list_create"),
|
re_path(r'^paymentModes$', PaymentModeListCreateView.as_view(), name="payment_mode_list_create"),
|
||||||
re_path(r'^paymentModes/(?P<id>[0-9]+)$', PaymentModeDetailView.as_view(), name="payment_mode_detail"),
|
re_path(r'^paymentModes/(?P<id>[0-9]+)$', PaymentModeDetailView.as_view(), name="payment_mode_detail"),
|
||||||
|
|
||||||
re_path(r'^domains$', DomainListCreateView.as_view(), name="domain_list_create"),
|
|
||||||
re_path(r'^domains/(?P<id>[0-9]+)$', DomainDetailView.as_view(), name="domain_detail"),
|
|
||||||
|
|
||||||
re_path(r'^categories$', CategoryListCreateView.as_view(), name="category_list_create"),
|
|
||||||
re_path(r'^categories/(?P<id>[0-9]+)$', CategoryDetailView.as_view(), name="category_detail"),
|
|
||||||
|
|
||||||
re_path(r'^competencies$', CompetencyListCreateView.as_view(), name="competency_list_create"),
|
|
||||||
re_path(r'^competencies/(?P<id>[0-9]+)$', CompetencyDetailView.as_view(), name="competency_detail"),
|
|
||||||
|
|
||||||
re_path(r'^establishmentCompetencies$', EstablishmentCompetencyListCreateView.as_view(), name="establishment_competency_list_create"),
|
re_path(r'^establishmentCompetencies$', EstablishmentCompetencyListCreateView.as_view(), name="establishment_competency_list_create"),
|
||||||
re_path(r'^establishmentCompetencies/(?P<id>[0-9]+)$', EstablishmentCompetencyDetailView.as_view(), name="establishment_competency_detail"),
|
re_path(r'^establishmentCompetencies/(?P<id>[0-9]+)$', EstablishmentCompetencyDetailView.as_view(), name="establishment_competency_detail"),
|
||||||
]
|
]
|
||||||
@ -13,9 +13,6 @@ from .models import (
|
|||||||
Fee,
|
Fee,
|
||||||
PaymentPlan,
|
PaymentPlan,
|
||||||
PaymentMode,
|
PaymentMode,
|
||||||
Domain,
|
|
||||||
Category,
|
|
||||||
Competency,
|
|
||||||
EstablishmentCompetency
|
EstablishmentCompetency
|
||||||
)
|
)
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
@ -27,11 +24,9 @@ from .serializers import (
|
|||||||
FeeSerializer,
|
FeeSerializer,
|
||||||
PaymentPlanSerializer,
|
PaymentPlanSerializer,
|
||||||
PaymentModeSerializer,
|
PaymentModeSerializer,
|
||||||
DomainSerializer,
|
|
||||||
CategorySerializer,
|
|
||||||
CompetencySerializer,
|
|
||||||
EstablishmentCompetencySerializer
|
EstablishmentCompetencySerializer
|
||||||
)
|
)
|
||||||
|
from Common.models import Domain, Category, Competency
|
||||||
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
from N3wtSchool.bdd import delete_object, getAllObjects, getObject
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
@ -422,156 +417,6 @@ class PaymentModeDetailView(APIView):
|
|||||||
def delete(self, request, id):
|
def delete(self, request, id):
|
||||||
return delete_object(PaymentMode, id)
|
return delete_object(PaymentMode, id)
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class DomainListCreateView(APIView):
|
|
||||||
def get(self, request):
|
|
||||||
domains = Domain.objects.all()
|
|
||||||
serializer = DomainSerializer(domains, many=True)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = DomainSerializer(data=data)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class DomainDetailView(APIView):
|
|
||||||
def get(self, request, id):
|
|
||||||
try:
|
|
||||||
domain = Domain.objects.get(id=id)
|
|
||||||
serializer = DomainSerializer(domain)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
except Domain.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
def put(self, request, id):
|
|
||||||
try:
|
|
||||||
domain = Domain.objects.get(id=id)
|
|
||||||
except Domain.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = DomainSerializer(domain, data=data, partial=True)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
def delete(self, request, id):
|
|
||||||
try:
|
|
||||||
domain = Domain.objects.get(id=id)
|
|
||||||
domain.delete()
|
|
||||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
|
||||||
except Domain.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
# Répète la même logique pour Category, Competency, EstablishmentCompetency
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class CategoryListCreateView(APIView):
|
|
||||||
def get(self, request):
|
|
||||||
categories = Category.objects.all()
|
|
||||||
serializer = CategorySerializer(categories, many=True)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = CategorySerializer(data=data)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class CategoryDetailView(APIView):
|
|
||||||
def get(self, request, id):
|
|
||||||
try:
|
|
||||||
category = Category.objects.get(id=id)
|
|
||||||
serializer = CategorySerializer(category)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
except Category.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
def put(self, request, id):
|
|
||||||
try:
|
|
||||||
category = Category.objects.get(id=id)
|
|
||||||
except Category.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = CategorySerializer(category, data=data, partial=True)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
def delete(self, request, id):
|
|
||||||
try:
|
|
||||||
category = Category.objects.get(id=id)
|
|
||||||
category.delete()
|
|
||||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
|
||||||
except Category.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class CompetencyListCreateView(APIView):
|
|
||||||
def get(self, request):
|
|
||||||
cycle = request.GET.get('cycle')
|
|
||||||
if cycle is None:
|
|
||||||
return JsonResponse({'error': 'cycle est requis'}, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
competencies_list = getAllObjects(Competency)
|
|
||||||
competencies_list = competencies_list.filter(
|
|
||||||
category__domain__cycle=cycle
|
|
||||||
).distinct()
|
|
||||||
serializer = CompetencySerializer(competencies_list, many=True)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = CompetencySerializer(data=data)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class CompetencyDetailView(APIView):
|
|
||||||
def get(self, request, id):
|
|
||||||
try:
|
|
||||||
competency = Competency.objects.get(id=id)
|
|
||||||
serializer = CompetencySerializer(competency)
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
except Competency.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
def put(self, request, id):
|
|
||||||
try:
|
|
||||||
competency = Competency.objects.get(id=id)
|
|
||||||
except Competency.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
data = JSONParser().parse(request)
|
|
||||||
serializer = CompetencySerializer(competency, data=data, partial=True)
|
|
||||||
if serializer.is_valid():
|
|
||||||
serializer.save()
|
|
||||||
return JsonResponse(serializer.data, safe=False)
|
|
||||||
return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
def delete(self, request, id):
|
|
||||||
try:
|
|
||||||
competency = Competency.objects.get(id=id)
|
|
||||||
competency.delete()
|
|
||||||
return JsonResponse({'message': 'Deleted'}, safe=False)
|
|
||||||
except Competency.DoesNotExist:
|
|
||||||
return JsonResponse({'error': 'No object found'}, status=status.HTTP_404_NOT_FOUND)
|
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
class EstablishmentCompetencyListCreateView(APIView):
|
class EstablishmentCompetencyListCreateView(APIView):
|
||||||
|
|||||||
@ -4,7 +4,6 @@ from django.conf import settings
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from School.models import PaymentModeType, PaymentPlanType
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -85,7 +84,7 @@ class Student(models.Model):
|
|||||||
last_name = models.CharField(max_length=200, default="")
|
last_name = models.CharField(max_length=200, default="")
|
||||||
first_name = models.CharField(max_length=200, default="")
|
first_name = models.CharField(max_length=200, default="")
|
||||||
gender = models.IntegerField(choices=StudentGender, default=StudentGender.NONE, blank=True)
|
gender = models.IntegerField(choices=StudentGender, default=StudentGender.NONE, blank=True)
|
||||||
level = models.IntegerField(choices=StudentLevel, default=StudentLevel.NONE, blank=True)
|
level = models.ForeignKey('Common.Level', on_delete=models.SET_NULL, null=True, blank=True, related_name='students')
|
||||||
nationality = models.CharField(max_length=200, default="", blank=True)
|
nationality = models.CharField(max_length=200, default="", blank=True)
|
||||||
address = models.CharField(max_length=200, default="", blank=True)
|
address = models.CharField(max_length=200, default="", blank=True)
|
||||||
birth_date = models.DateField(null=True, blank=True)
|
birth_date = models.DateField(null=True, blank=True)
|
||||||
@ -247,10 +246,10 @@ class RegistrationForm(models.Model):
|
|||||||
blank=True)
|
blank=True)
|
||||||
|
|
||||||
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='register_forms')
|
establishment = models.ForeignKey('Establishment.Establishment', on_delete=models.CASCADE, related_name='register_forms')
|
||||||
registration_payment = models.ForeignKey('School.PaymentModeType', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_modes_forms')
|
registration_payment = models.ForeignKey('School.PaymentMode', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_modes_forms')
|
||||||
tuition_payment = models.ForeignKey('School.PaymentModeType', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_modes_forms')
|
tuition_payment = models.ForeignKey('School.PaymentMode', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_modes_forms')
|
||||||
registration_payment_plan = models.ForeignKey('School.PaymentPlanType', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_plans_forms')
|
registration_payment_plan = models.ForeignKey('School.PaymentPlan', on_delete=models.SET_NULL, null=True, blank=True, related_name='registration_payment_plans_forms')
|
||||||
tuition_payment_plan = models.ForeignKey('School.PaymentPlanType', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_plans_forms')
|
tuition_payment_plan = models.ForeignKey('School.PaymentPlan', on_delete=models.SET_NULL, null=True, blank=True, related_name='tuition_payment_plans_forms')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
return "RF_" + self.student.last_name + "_" + self.student.first_name
|
||||||
@ -323,6 +322,18 @@ class RegistrationSchoolFileTemplate(models.Model):
|
|||||||
filenames.append(reg_file.file.path)
|
filenames.append(reg_file.file.path)
|
||||||
return filenames
|
return filenames
|
||||||
|
|
||||||
|
class StudentCompetency(models.Model):
|
||||||
|
student = models.ForeignKey('Subscriptions.Student', on_delete=models.CASCADE, related_name='competency_scores')
|
||||||
|
competency = models.ForeignKey('Common.Competency', on_delete=models.CASCADE, related_name='student_scores')
|
||||||
|
score = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
|
||||||
|
comment = models.TextField(blank=True, null=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('student', 'competency')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.student} - {self.competency.name} - Score: {self.score}"
|
||||||
|
|
||||||
####### Parent files templates (par dossier d'inscription) #######
|
####### Parent files templates (par dossier d'inscription) #######
|
||||||
class RegistrationParentFileTemplate(models.Model):
|
class RegistrationParentFileTemplate(models.Model):
|
||||||
master = models.ForeignKey(RegistrationParentFileMaster, on_delete=models.CASCADE, related_name='parent_file_templates', blank=True)
|
master = models.ForeignKey(RegistrationParentFileMaster, on_delete=models.CASCADE, related_name='parent_file_templates', blank=True)
|
||||||
|
|||||||
@ -1,5 +1,17 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from .models import RegistrationFileGroup, RegistrationForm, Student, Guardian, Sibling, Language, RegistrationSchoolFileMaster, RegistrationSchoolFileTemplate, RegistrationParentFileMaster, RegistrationParentFileTemplate, AbsenceManagement
|
from .models import (
|
||||||
|
RegistrationFileGroup,
|
||||||
|
RegistrationForm,
|
||||||
|
Student,
|
||||||
|
Guardian,
|
||||||
|
Sibling,
|
||||||
|
Language,
|
||||||
|
RegistrationSchoolFileMaster,
|
||||||
|
RegistrationSchoolFileTemplate,
|
||||||
|
RegistrationParentFileMaster,
|
||||||
|
RegistrationParentFileTemplate,
|
||||||
|
AbsenceManagement
|
||||||
|
)
|
||||||
from School.models import SchoolClass, Fee, Discount, FeeType
|
from School.models import SchoolClass, Fee, Discount, FeeType
|
||||||
from School.serializers import FeeSerializer, DiscountSerializer
|
from School.serializers import FeeSerializer, DiscountSerializer
|
||||||
from Auth.models import ProfileRole, Profile
|
from Auth.models import ProfileRole, Profile
|
||||||
@ -406,15 +418,19 @@ class GuardianByDICreationSerializer(serializers.ModelSerializer):
|
|||||||
class StudentByRFCreationSerializer(serializers.ModelSerializer):
|
class StudentByRFCreationSerializer(serializers.ModelSerializer):
|
||||||
id = serializers.IntegerField(required=False)
|
id = serializers.IntegerField(required=False)
|
||||||
guardians = GuardianByDICreationSerializer(many=True, required=False)
|
guardians = GuardianByDICreationSerializer(many=True, required=False)
|
||||||
|
associated_class_name = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Student
|
model = Student
|
||||||
fields = ['id', 'last_name', 'first_name', 'guardians', 'level']
|
fields = ['id', 'last_name', 'first_name', 'guardians', 'level', 'associated_class_name']
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(StudentByRFCreationSerializer, self).__init__(*args, **kwargs)
|
super(StudentByRFCreationSerializer, self).__init__(*args, **kwargs)
|
||||||
for field in self.fields:
|
for field in self.fields:
|
||||||
self.fields[field].required = False
|
self.fields[field].required = False
|
||||||
|
|
||||||
|
def get_associated_class_name(self, obj):
|
||||||
|
return obj.associated_class.atmosphere_name if obj.associated_class else None
|
||||||
|
|
||||||
class NotificationSerializer(serializers.ModelSerializer):
|
class NotificationSerializer(serializers.ModelSerializer):
|
||||||
notification_type_label = serializers.ReadOnlyField()
|
notification_type_label = serializers.ReadOnlyField()
|
||||||
|
|||||||
@ -35,7 +35,10 @@ def getTuitionPaymentMethod(pk):
|
|||||||
@register.filter
|
@register.filter
|
||||||
def getStudentLevel(pk):
|
def getStudentLevel(pk):
|
||||||
registerForm = RegistrationForm.objects.get(student=pk)
|
registerForm = RegistrationForm.objects.get(student=pk)
|
||||||
return Student.StudentLevel(int(registerForm.student.level)).label
|
level = registerForm.student.level
|
||||||
|
if level:
|
||||||
|
return level.name
|
||||||
|
return ""
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def getStudentGender(pk):
|
def getStudentGender(pk):
|
||||||
|
|||||||
@ -17,7 +17,9 @@ from .views import (
|
|||||||
RegistrationParentFileTemplateSimpleView,
|
RegistrationParentFileTemplateSimpleView,
|
||||||
RegistrationParentFileTemplateView,
|
RegistrationParentFileTemplateView,
|
||||||
AbsenceManagementListCreateView,
|
AbsenceManagementListCreateView,
|
||||||
AbsenceManagementDetailView
|
AbsenceManagementDetailView,
|
||||||
|
StudentCompetencyListCreateView,
|
||||||
|
StudentCompetencySimpleView
|
||||||
)
|
)
|
||||||
|
|
||||||
from .views import RegistrationFileGroupView, RegistrationFileGroupSimpleView, get_registration_files_by_group
|
from .views import RegistrationFileGroupView, RegistrationFileGroupSimpleView, get_registration_files_by_group
|
||||||
@ -63,4 +65,7 @@ urlpatterns = [
|
|||||||
re_path(r'^absences$', AbsenceManagementListCreateView.as_view(), name="absence_list_create"),
|
re_path(r'^absences$', AbsenceManagementListCreateView.as_view(), name="absence_list_create"),
|
||||||
re_path(r'^absences/(?P<id>[0-9]+)$', AbsenceManagementDetailView.as_view(), name="absence_detail"),
|
re_path(r'^absences/(?P<id>[0-9]+)$', AbsenceManagementDetailView.as_view(), name="absence_detail"),
|
||||||
|
|
||||||
|
re_path(r'^studentCompetencies$', StudentCompetencyListCreateView.as_view(), name="student_competency_list_create"),
|
||||||
|
re_path(r'^studentCompetencies/(?P<id>[0-9]+)$', StudentCompetencySimpleView.as_view(), name="student_competency_detail"),
|
||||||
|
|
||||||
]
|
]
|
||||||
@ -13,6 +13,7 @@ from .registration_file_group_views import RegistrationFileGroupView, Registrati
|
|||||||
from .student_views import StudentView, StudentListView, ChildrenListView
|
from .student_views import StudentView, StudentListView, ChildrenListView
|
||||||
from .guardian_views import GuardianView, DissociateGuardianView
|
from .guardian_views import GuardianView, DissociateGuardianView
|
||||||
from .absences_views import AbsenceManagementDetailView, AbsenceManagementListCreateView
|
from .absences_views import AbsenceManagementDetailView, AbsenceManagementListCreateView
|
||||||
|
from .student_competencies_views import StudentCompetencyListCreateView, StudentCompetencySimpleView
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'RegisterFormView',
|
'RegisterFormView',
|
||||||
@ -39,5 +40,7 @@ __all__ = [
|
|||||||
'GuardianView',
|
'GuardianView',
|
||||||
'DissociateGuardianView',
|
'DissociateGuardianView',
|
||||||
'AbsenceManagementDetailView',
|
'AbsenceManagementDetailView',
|
||||||
'AbsenceManagementListCreateView'
|
'AbsenceManagementListCreateView',
|
||||||
|
'StudentCompetencyListCreateView',
|
||||||
|
'StudentCompetencySimpleView'
|
||||||
]
|
]
|
||||||
|
|||||||
@ -16,10 +16,22 @@ import Subscriptions.util as util
|
|||||||
|
|
||||||
from Subscriptions.serializers import RegistrationFormSerializer, RegistrationSchoolFileTemplateSerializer, RegistrationParentFileTemplateSerializer
|
from Subscriptions.serializers import RegistrationFormSerializer, RegistrationSchoolFileTemplateSerializer, RegistrationParentFileTemplateSerializer
|
||||||
from Subscriptions.pagination import CustomSubscriptionPagination
|
from Subscriptions.pagination import CustomSubscriptionPagination
|
||||||
from Subscriptions.models import Student, Guardian, RegistrationForm, RegistrationSchoolFileTemplate, RegistrationFileGroup, RegistrationParentFileTemplate
|
from Subscriptions.models import (
|
||||||
|
Student,
|
||||||
|
Guardian,
|
||||||
|
RegistrationForm,
|
||||||
|
RegistrationSchoolFileTemplate,
|
||||||
|
RegistrationFileGroup,
|
||||||
|
RegistrationParentFileTemplate,
|
||||||
|
StudentCompetency
|
||||||
|
)
|
||||||
from Subscriptions.automate import updateStateMachine
|
from Subscriptions.automate import updateStateMachine
|
||||||
|
from Common.models import Competency
|
||||||
|
|
||||||
from N3wtSchool import settings, bdd
|
from N3wtSchool import settings, bdd
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -236,7 +248,6 @@ class RegisterFormWithIdView(APIView):
|
|||||||
studentForm_data = request.data.get('data', '{}')
|
studentForm_data = request.data.get('data', '{}')
|
||||||
try:
|
try:
|
||||||
data = json.loads(studentForm_data)
|
data = json.loads(studentForm_data)
|
||||||
print(f'data : {data}')
|
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
return JsonResponse({"error": "Invalid JSON format in 'data'"}, status=status.HTTP_400_BAD_REQUEST)
|
return JsonResponse({"error": "Invalid JSON format in 'data'"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
@ -366,6 +377,26 @@ class RegisterFormWithIdView(APIView):
|
|||||||
save=True
|
save=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Valorisation des StudentCompetency pour l'élève
|
||||||
|
try:
|
||||||
|
student = registerForm.student
|
||||||
|
cycle = None
|
||||||
|
if student.level:
|
||||||
|
cycle = student.level.cycle.number
|
||||||
|
if cycle:
|
||||||
|
competencies = Competency.objects.filter(
|
||||||
|
category__domain__cycle=cycle
|
||||||
|
).filter(
|
||||||
|
Q(end_of_cycle=True) | Q(level=student.level.name)
|
||||||
|
)
|
||||||
|
for comp in competencies:
|
||||||
|
StudentCompetency.objects.get_or_create(
|
||||||
|
student=student,
|
||||||
|
competency=comp
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Erreur lors de la valorisation des StudentCompetency: {e}")
|
||||||
|
|
||||||
updateStateMachine(registerForm, 'EVENT_VALIDATE')
|
updateStateMachine(registerForm, 'EVENT_VALIDATE')
|
||||||
|
|
||||||
# Retourner les données mises à jour
|
# Retourner les données mises à jour
|
||||||
|
|||||||
91
Back-End/Subscriptions/views/student_competencies_views.py
Normal file
91
Back-End/Subscriptions/views/student_competencies_views.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
from django.http.response import JsonResponse
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework import status
|
||||||
|
from drf_yasg.utils import swagger_auto_schema
|
||||||
|
from drf_yasg import openapi
|
||||||
|
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_protect
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from Subscriptions.models import StudentCompetency, Student
|
||||||
|
from Common.models import Domain, Competency
|
||||||
|
from N3wtSchool.bdd import delete_object
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class StudentCompetencyListCreateView(APIView):
|
||||||
|
def get(self, request):
|
||||||
|
student_id = request.GET.get('student_id')
|
||||||
|
if not student_id:
|
||||||
|
return JsonResponse({'error': 'student_id requis'}, status=400)
|
||||||
|
try:
|
||||||
|
student = Student.objects.get(id=student_id)
|
||||||
|
except Student.DoesNotExist:
|
||||||
|
return JsonResponse({'error': 'Élève introuvable'}, status=404)
|
||||||
|
|
||||||
|
student_competencies = StudentCompetency.objects.filter(student=student).select_related('competency', 'competency__category', 'competency__category__domain')
|
||||||
|
|
||||||
|
# On ne garde que les IDs des compétences de l'élève
|
||||||
|
student_competency_ids = set(sc.competency_id for sc in student_competencies)
|
||||||
|
|
||||||
|
result = []
|
||||||
|
total_competencies = 0
|
||||||
|
domaines = Domain.objects.all()
|
||||||
|
for domaine in domaines:
|
||||||
|
domaine_dict = {
|
||||||
|
"domaine_id": domaine.id,
|
||||||
|
"domaine_nom": domaine.name,
|
||||||
|
"categories": []
|
||||||
|
}
|
||||||
|
categories = domaine.categories.all()
|
||||||
|
for categorie in categories:
|
||||||
|
categorie_dict = {
|
||||||
|
"categorie_id": categorie.id,
|
||||||
|
"categorie_nom": categorie.name,
|
||||||
|
"competences": []
|
||||||
|
}
|
||||||
|
# On ne boucle que sur les compétences du student pour cette catégorie
|
||||||
|
for sc in student_competencies:
|
||||||
|
comp = sc.competency
|
||||||
|
if comp.category_id == categorie.id:
|
||||||
|
categorie_dict["competences"].append({
|
||||||
|
"competence_id": comp.id,
|
||||||
|
"nom": comp.name,
|
||||||
|
"score": sc.score,
|
||||||
|
"comment": sc.comment or "",
|
||||||
|
})
|
||||||
|
total_competencies += 1
|
||||||
|
if categorie_dict["competences"]:
|
||||||
|
domaine_dict["categories"].append(categorie_dict)
|
||||||
|
if domaine_dict["categories"]:
|
||||||
|
result.append(domaine_dict)
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
"count": total_competencies,
|
||||||
|
"data": result
|
||||||
|
}, safe=False, status=200)
|
||||||
|
|
||||||
|
# def post(self, request):
|
||||||
|
# serializer = AbsenceManagementSerializer(data=request.data)
|
||||||
|
# if serializer.is_valid():
|
||||||
|
# serializer.save()
|
||||||
|
# return JsonResponse(serializer.data, safe=False, status=status.HTTP_201_CREATED)
|
||||||
|
# return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
||||||
|
class StudentCompetencySimpleView(APIView):
|
||||||
|
def get(self, request, id):
|
||||||
|
return JsonResponse("ok", safe=False, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
# def put(self, request, id):
|
||||||
|
# try:
|
||||||
|
# absence = AbsenceManagement.objects.get(id=id)
|
||||||
|
# serializer = AbsenceManagementSerializer(absence, data=request.data)
|
||||||
|
# if serializer.is_valid():
|
||||||
|
# serializer.save()
|
||||||
|
# return JsonResponse(serializer.data, safe=False, status=status.HTTP_200_OK)
|
||||||
|
# return JsonResponse(serializer.errors, safe=False, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
# except AbsenceManagement.DoesNotExist:
|
||||||
|
# return JsonResponse({"error": "Absence not found"}, safe=False, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
# def delete(self, request, id):
|
||||||
|
# return delete_object(AbsenceManagement, id)
|
||||||
@ -10,6 +10,7 @@ APPS = [
|
|||||||
"GestionMessagerie",
|
"GestionMessagerie",
|
||||||
"Auth",
|
"Auth",
|
||||||
"School",
|
"School",
|
||||||
|
"Common"
|
||||||
]
|
]
|
||||||
|
|
||||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|||||||
@ -15,6 +15,7 @@ test_mode = os.getenv('TEST_MODE', 'False') == 'True'
|
|||||||
commands = [
|
commands = [
|
||||||
["python", "manage.py", "collectstatic", "--noinput"],
|
["python", "manage.py", "collectstatic", "--noinput"],
|
||||||
["python", "manage.py", "flush", "--noinput"],
|
["python", "manage.py", "flush", "--noinput"],
|
||||||
|
["python", "manage.py", "makemigrations", "Common", "--noinput"],
|
||||||
["python", "manage.py", "makemigrations", "Establishment", "--noinput"],
|
["python", "manage.py", "makemigrations", "Establishment", "--noinput"],
|
||||||
["python", "manage.py", "makemigrations", "Settings", "--noinput"],
|
["python", "manage.py", "makemigrations", "Settings", "--noinput"],
|
||||||
["python", "manage.py", "makemigrations", "Subscriptions", "--noinput"],
|
["python", "manage.py", "makemigrations", "Subscriptions", "--noinput"],
|
||||||
|
|||||||
Reference in New Issue
Block a user