Add API support
This commit is contained in:
parent
54de82af42
commit
fe1914b5a5
|
@ -148,7 +148,8 @@ class Term(models.Model):
|
||||||
.annotate(base_vol=Count("groups__members"))
|
.annotate(base_vol=Count("groups__members"))
|
||||||
.annotate(swap_plus=Count("swap", filter=Q(swap__enroll=1), distinct=True))
|
.annotate(swap_plus=Count("swap", filter=Q(swap__enroll=1), distinct=True))
|
||||||
.annotate(swap_minus=Count("swap", filter=Q(swap__enroll=0), distinct=True))
|
.annotate(swap_minus=Count("swap", filter=Q(swap__enroll=0), distinct=True))
|
||||||
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus")))
|
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus"))
|
||||||
|
.order_by())
|
||||||
|
|
||||||
def query_colles_of_student(self, student) -> QuerySet:
|
def query_colles_of_student(self, student) -> QuerySet:
|
||||||
has_student = ((Q(groups__student=student)
|
has_student = ((Q(groups__student=student)
|
||||||
|
@ -164,6 +165,7 @@ class Term(models.Model):
|
||||||
.annotate(swap_minus=Count("pk", filter=Q(swap__enroll=0), distinct=True))
|
.annotate(swap_minus=Count("pk", filter=Q(swap__enroll=0), distinct=True))
|
||||||
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus"))
|
.annotate(volume=F("base_vol") + F("swap_plus") - F("swap_minus"))
|
||||||
.filter(has_student)
|
.filter(has_student)
|
||||||
|
.order_by()
|
||||||
)
|
)
|
||||||
|
|
||||||
def query_colles_not_full_excluding_student(self, student) -> QuerySet:
|
def query_colles_not_full_excluding_student(self, student) -> QuerySet:
|
||||||
|
@ -184,6 +186,9 @@ class Subject(models.Model):
|
||||||
description = models.CharField(max_length=100)
|
description = models.CharField(max_length=100)
|
||||||
code = models.CharField(max_length=20)
|
code = models.CharField(max_length=20)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ["description"]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.description
|
return self.description
|
||||||
|
|
||||||
|
@ -292,6 +297,7 @@ class Slot(models.Model):
|
||||||
capacity = models.IntegerField()
|
capacity = models.IntegerField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
ordering = ["subject", "colleur", "day", "time"]
|
||||||
verbose_name_plural = "slots"
|
verbose_name_plural = "slots"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
from rest_framework.serializers import ModelSerializer
|
||||||
|
|
||||||
|
from colloscope.models import *
|
||||||
|
|
||||||
|
|
||||||
|
class SchoolSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = School
|
||||||
|
fields = ["id", "uai", "description", "vacation"]
|
||||||
|
|
||||||
|
|
||||||
|
class StudentSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Student
|
||||||
|
fields = ["id", "cls", "first_name", "last_name", "groups"]
|
||||||
|
|
||||||
|
|
||||||
|
class ClassSerializer(ModelSerializer):
|
||||||
|
students = StudentSerializer(source="student_set", many=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Class
|
||||||
|
fields = ["id", "school", "description", "year", "day_zero", "students"]
|
||||||
|
|
||||||
|
|
||||||
|
class TermSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Term
|
||||||
|
fields = ["id", "cls", "description", "begin", "end"]
|
||||||
|
|
||||||
|
|
||||||
|
class SubjectSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Subject
|
||||||
|
fields = ["id", "cls", "description", "code"]
|
||||||
|
|
||||||
|
|
||||||
|
class GroupTypeSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = GroupType
|
||||||
|
fields = ["id", "term", "description"]
|
||||||
|
|
||||||
|
|
||||||
|
class GroupSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Group
|
||||||
|
fields = ["id", "term", "description", "members"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ColleurSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Colleur
|
||||||
|
fields = ["id", "gender", "name"]
|
||||||
|
|
||||||
|
|
||||||
|
class SlotSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Slot
|
||||||
|
fields = ["id", "term", "day", "time", "duration", "room", "subject", "colleur", "type", "capacity"]
|
||||||
|
|
||||||
|
|
||||||
|
class ColleSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Colle
|
||||||
|
fields = ["id", "slot", "groups", "date"]
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarLinkSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = CalendarLink
|
||||||
|
fields = ["id", "key", "student", "term"]
|
|
@ -0,0 +1,82 @@
|
||||||
|
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
|
||||||
|
|
||||||
|
from colloscope.models import *
|
||||||
|
from colloscope.serializers import *
|
||||||
|
|
||||||
|
|
||||||
|
class SchoolViewset(ReadOnlyModelViewSet):
|
||||||
|
|
||||||
|
serializer_class = SchoolSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return School.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ClassViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = ClassSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Class.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class TermViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = TermSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Term.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class SubjectViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = SubjectSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Subject.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class GroupTypeViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = GroupTypeSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return GroupType.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class GroupViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = GroupSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Group.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class StudentViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = StudentSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Student.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ColleurViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = ColleurSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Colleur.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class SlotViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = SlotSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Slot.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ColleViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = ColleSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Colle.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class CalendarLinkViewset(ReadOnlyModelViewSet):
|
||||||
|
serializer_class = CalendarLinkSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return CalendarLink.objects.all()
|
|
@ -42,16 +42,21 @@ CORS_ORIGIN_WHITELIST = [
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
"daphne",
|
"daphne",
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
|
'oauth2_provider',
|
||||||
|
'corsheaders',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.messages',
|
'django.contrib.messages',
|
||||||
'django.contrib.staticfiles',
|
'django.contrib.staticfiles',
|
||||||
|
"rest_framework",
|
||||||
'colloscope',
|
'colloscope',
|
||||||
|
"drf_spectacular",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'corsheaders.middleware.CorsMiddleware',
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
|
@ -163,4 +168,20 @@ EMAIL_HOST = "pulp.o2switch.net"
|
||||||
EMAIL_PORT = 587
|
EMAIL_PORT = 587
|
||||||
EMAIL_HOST_USER = "colloscope@mp2i-vms.fr"
|
EMAIL_HOST_USER = "colloscope@mp2i-vms.fr"
|
||||||
EMAIL_HOST_PASSWORD = "phoBTchc2vVaq$PefsntT9M7"
|
EMAIL_HOST_PASSWORD = "phoBTchc2vVaq$PefsntT9M7"
|
||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
|
||||||
|
'PAGE_SIZE': 10,
|
||||||
|
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SPECTACULAR_SETTINGS = {
|
||||||
|
'TITLE': 'Colloscope API',
|
||||||
|
'DESCRIPTION': 'Gérer les colles de prépa devient facile',
|
||||||
|
'VERSION': '1.0.0',
|
||||||
|
'SERVE_INCLUDE_SCHEMA': False,
|
||||||
|
# OTHER SETTINGS
|
||||||
|
}
|
||||||
|
|
|
@ -17,11 +17,35 @@ Including another URLconf
|
||||||
from django.contrib import admin, auth
|
from django.contrib import admin, auth
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
from django.contrib.staticfiles import views as vstatic
|
from django.contrib.staticfiles import views as vstatic
|
||||||
|
from rest_framework import routers
|
||||||
|
from drf_spectacular.views import SpectacularAPIView, SpectacularRedocView, SpectacularSwaggerView
|
||||||
|
|
||||||
from colloscope.views import home_redirect
|
from colloscope.views import home_redirect
|
||||||
|
from colloscope.viewsets import *
|
||||||
|
|
||||||
|
router = routers.SimpleRouter()
|
||||||
|
router.register('school', SchoolViewset, basename='school')
|
||||||
|
router.register('class', ClassViewset, basename='class')
|
||||||
|
router.register('term', TermViewset, basename='term')
|
||||||
|
router.register("subject", SubjectViewset, basename='subject')
|
||||||
|
router.register('grouptype', GroupTypeViewset, basename='grouptype')
|
||||||
|
router.register("group", GroupViewset, basename='group')
|
||||||
|
router.register("student", StudentViewset, basename='student')
|
||||||
|
router.register("colleur", ColleurViewset, basename='colleur')
|
||||||
|
router.register("slot", SlotViewset, basename='slot')
|
||||||
|
router.register("colle", ColleViewset, basename='colle')
|
||||||
|
router.register("calendarlink", CalendarLinkViewset, basename='calendarlink')
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', home_redirect, name="home"),
|
path('', home_redirect, name="home"),
|
||||||
|
path('api-auth/', include('rest_framework.urls')),
|
||||||
|
path("api/", include(router.urls)),
|
||||||
|
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
|
||||||
|
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
|
||||||
|
path('api/schema/redoc/', SpectacularRedocView.as_view(url_name='schema'), name='redoc'),
|
||||||
|
|
||||||
|
path("oauth2/", include('oauth2_provider.urls', namespace='oauth2_provider')),
|
||||||
path("favicon.ico", lambda req: vstatic.serve(req, "favicon.ico")),
|
path("favicon.ico", lambda req: vstatic.serve(req, "favicon.ico")),
|
||||||
path('colloscope/', include('colloscope.urls')),
|
path('colloscope/', include('colloscope.urls')),
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
aiohttp==3.9.5
|
||||||
|
aiosignal==1.3.1
|
||||||
|
asgiref==3.8.1
|
||||||
|
attrs==23.2.0
|
||||||
|
autobahn==23.6.2
|
||||||
|
Automat==22.10.0
|
||||||
|
certifi==2024.2.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
constantly==23.10.4
|
||||||
|
cryptography==42.0.5
|
||||||
|
daphne==4.1.2
|
||||||
|
defusedxml==0.7.1
|
||||||
|
discord.py==2.3.2
|
||||||
|
Django==5.0.4
|
||||||
|
django-cors-headers==4.3.1
|
||||||
|
django-oauth-toolkit==2.3.0
|
||||||
|
django-smtp-ssl==1.0
|
||||||
|
djangorestframework==3.15.1
|
||||||
|
drf-spectacular==0.27.2
|
||||||
|
fonttools==4.51.0
|
||||||
|
fpdf2==2.7.8
|
||||||
|
frozenlist==1.4.1
|
||||||
|
hyperlink==21.0.0
|
||||||
|
icalendar==5.0.12
|
||||||
|
idna==3.7
|
||||||
|
incremental==22.10.0
|
||||||
|
inflection==0.5.1
|
||||||
|
jsonschema==4.22.0
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
jwcrypto==1.5.6
|
||||||
|
multidict==6.0.5
|
||||||
|
numpy==1.26.4
|
||||||
|
oauthlib==3.2.2
|
||||||
|
pandas==2.2.2
|
||||||
|
pillow==10.3.0
|
||||||
|
pyasn1==0.6.0
|
||||||
|
pyasn1_modules==0.4.0
|
||||||
|
pycparser==2.22
|
||||||
|
pyOpenSSL==24.1.0
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
pytz==2024.1
|
||||||
|
PyYAML==6.0.1
|
||||||
|
referencing==0.35.1
|
||||||
|
requests==2.31.0
|
||||||
|
rpds-py==0.18.0
|
||||||
|
service-identity==24.1.0
|
||||||
|
setuptools==69.5.1
|
||||||
|
six==1.16.0
|
||||||
|
sqlparse==0.4.4
|
||||||
|
Twisted==24.3.0
|
||||||
|
txaio==23.1.1
|
||||||
|
typing_extensions==4.11.0
|
||||||
|
tzdata==2024.1
|
||||||
|
uritemplate==4.1.1
|
||||||
|
urllib3==2.2.1
|
||||||
|
yarl==1.9.4
|
||||||
|
zope.interface==6.3
|
Loading…
Reference in New Issue