base for API system (routes + filters)
This commit is contained in:
parent
23c79e2284
commit
6dcc3a448e
10 changed files with 401 additions and 14 deletions
0
Palto/Palto/api/__init__.py
Normal file
0
Palto/Palto/api/__init__.py
Normal file
7
Palto/Palto/api/urls.py
Normal file
7
Palto/Palto/api/urls.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
import Palto.Palto.api.v1.urls as v1_urls
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
# API
|
||||||
|
path('v1/', include(v1_urls)),
|
||||||
|
]
|
0
Palto/Palto/api/v1/__init__.py
Normal file
0
Palto/Palto/api/v1/__init__.py
Normal file
63
Palto/Palto/api/v1/serializers.py
Normal file
63
Palto/Palto/api/v1/serializers.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
from rest_framework import serializers
|
||||||
|
|
||||||
|
from Palto.Palto.models import (User, Department, TeachingUnit, StudentCard, TeachingSession, Attendance, Absence,
|
||||||
|
AbsenceAttachment, StudentGroup)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO(Raphaël): Les champs sont-ils sûr ? (carte uid ?)
|
||||||
|
# TODO(Raphaël): Connection à l'API avec token ?
|
||||||
|
# TODO(Raphaël): Voir pour les relations
|
||||||
|
|
||||||
|
|
||||||
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
fields = ['id', 'username', 'first_name', 'last_name']
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Department
|
||||||
|
fields = ['id', 'name', 'mail']
|
||||||
|
|
||||||
|
|
||||||
|
class StudentGroupSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = StudentGroup
|
||||||
|
fields = ['id', 'name']
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingUnitSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TeachingUnit
|
||||||
|
fields = ['id', 'name', 'department']
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCardSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = StudentCard
|
||||||
|
fields = ['id', 'uid', 'owner']
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingSessionSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TeachingSession
|
||||||
|
fields = ['id', 'start', 'duration', 'note', 'unit', 'group', 'teacher']
|
||||||
|
|
||||||
|
|
||||||
|
class AttendanceSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Attendance
|
||||||
|
fields = ['id', 'date', 'student']
|
||||||
|
|
||||||
|
|
||||||
|
class AbsenceSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Absence
|
||||||
|
fields = ['id', 'message', 'student']
|
||||||
|
|
||||||
|
|
||||||
|
class AbsenceAttachmentSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = AbsenceAttachment
|
||||||
|
fields = ['id', 'content', 'absence']
|
19
Palto/Palto/api/v1/urls.py
Normal file
19
Palto/Palto/api/v1/urls.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
from rest_framework import routers
|
||||||
|
|
||||||
|
from .views import (UserViewSet, AbsenceAttachmentViewSet, AbsenceViewSet, AttendanceViewSet, TeachingSessionViewSet,
|
||||||
|
StudentCardViewSet, TeachingUnitViewSet, StudentGroupViewSet, DepartmentViewSet)
|
||||||
|
|
||||||
|
router = routers.DefaultRouter()
|
||||||
|
|
||||||
|
router.register(r'users', UserViewSet, basename="User")
|
||||||
|
router.register(r'departments', DepartmentViewSet, basename="Department")
|
||||||
|
router.register(r'student_groups', StudentGroupViewSet, basename="StudentGroup")
|
||||||
|
router.register(r'teaching_units', TeachingUnitViewSet, basename="TeachingUnit")
|
||||||
|
router.register(r'student_cards', StudentCardViewSet, basename="StudentCard")
|
||||||
|
router.register(r'teaching_sessions', TeachingSessionViewSet, basename="TeachingSession")
|
||||||
|
router.register(r'attendances', AttendanceViewSet, basename="Attendance")
|
||||||
|
router.register(r'absences', AbsenceViewSet, basename="Absence")
|
||||||
|
router.register(r'absence_attachments', AbsenceAttachmentViewSet, basename="AbsenceAttachment")
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = router.urls
|
81
Palto/Palto/api/v1/views.py
Normal file
81
Palto/Palto/api/v1/views.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
from rest_framework import viewsets
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
||||||
|
from .serializers import (UserSerializer, AbsenceAttachmentSerializer, AbsenceSerializer, AttendanceSerializer,
|
||||||
|
TeachingSessionSerializer, StudentCardSerializer, StudentGroupSerializer,
|
||||||
|
DepartmentSerializer, TeachingUnitSerializer)
|
||||||
|
from ...models import (User, AbsenceAttachment, Absence, Attendance, TeachingSession, StudentCard, TeachingUnit,
|
||||||
|
StudentGroup, Department)
|
||||||
|
|
||||||
|
|
||||||
|
class UserViewSet(viewsets.ModelViewSet):
|
||||||
|
serializer_class = UserSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return User.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
def get_permissions(self):
|
||||||
|
return User.permissions_for(self.request.user, self.request.method)
|
||||||
|
|
||||||
|
|
||||||
|
class DepartmentViewSet(UserViewSet):
|
||||||
|
serializer_class = DepartmentSerializer
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Department.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class StudentGroupViewSet(UserViewSet):
|
||||||
|
serializer_class = StudentGroupSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return StudentGroup.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingUnitViewSet(UserViewSet):
|
||||||
|
serializer_class = TeachingUnitSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return TeachingUnit.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCardViewSet(UserViewSet):
|
||||||
|
serializer_class = StudentCardSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return StudentCard.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingSessionViewSet(UserViewSet):
|
||||||
|
serializer_class = TeachingSessionSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return TeachingSession.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class AttendanceViewSet(UserViewSet):
|
||||||
|
serializer_class = AttendanceSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Attendance.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class AbsenceViewSet(UserViewSet):
|
||||||
|
serializer_class = AbsenceSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Absence.all_visible_to(self.request.user)
|
||||||
|
|
||||||
|
|
||||||
|
class AbsenceAttachmentViewSet(UserViewSet):
|
||||||
|
serializer_class = AbsenceAttachmentSerializer
|
||||||
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return AbsenceAttachment.all_visible_to(self.request.user)
|
|
@ -1,13 +1,33 @@
|
||||||
import uuid
|
import uuid
|
||||||
|
from abc import abstractmethod, ABC
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Iterable
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import QuerySet, Q
|
||||||
|
from rest_framework import permissions
|
||||||
|
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class User(AbstractUser):
|
class ModelApiMixin(ABC):
|
||||||
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet:
|
||||||
|
"""
|
||||||
|
Return all the objects visible to a user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@abstractmethod
|
||||||
|
def permissions_for(cls, user: "User", method: str) -> permissions.BasePermission:
|
||||||
|
"""
|
||||||
|
Return the permissions for a user and the method used to access the object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class User(AbstractUser, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A user.
|
A user.
|
||||||
|
|
||||||
|
@ -19,8 +39,45 @@ class User(AbstractUser):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} id={str(self.id)[:8]} username={self.username!r}>"
|
return f"<{self.__class__.__name__} id={str(self.id)[:8]} username={self.username!r}>"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def multiple_related_departments(users: Iterable["User"]) -> QuerySet["Department"]:
|
||||||
|
"""
|
||||||
|
Return all the related departments from multiple users.
|
||||||
|
"""
|
||||||
|
|
||||||
class Department(models.Model):
|
return Department.objects.filter(
|
||||||
|
Q(managers__in=users) |
|
||||||
|
Q(teachers__in=users) |
|
||||||
|
Q(students__in=users)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def related_departments(self) -> QuerySet["Department"]:
|
||||||
|
"""
|
||||||
|
The list of departments related with the user.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.multiple_related_departments([self])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = User.objects.all()
|
||||||
|
else:
|
||||||
|
queryset = Department.multiple_related_users(user.related_departments)
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def permissions_for(cls, user: "User", method: str) -> permissions.BasePermission:
|
||||||
|
# TODO: ???
|
||||||
|
if method in permissions.SAFE_METHODS:
|
||||||
|
return permissions.AllowAny()
|
||||||
|
|
||||||
|
return permissions.IsAdminUser()
|
||||||
|
|
||||||
|
|
||||||
|
class Department(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A scholar department.
|
A scholar department.
|
||||||
|
|
||||||
|
@ -42,8 +99,32 @@ class Department(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def multiple_related_users(departments: Iterable["Department"]) -> QuerySet["User"]:
|
||||||
|
"""
|
||||||
|
Return all the related users from multiple departments.
|
||||||
|
"""
|
||||||
|
|
||||||
class StudentGroup(models.Model):
|
return User.objects.filter(
|
||||||
|
Q(managing_departments__in=departments) |
|
||||||
|
Q(teaching_departments__in=departments) |
|
||||||
|
Q(studying_departments__in=departments)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def related_users(self) -> QuerySet["User"]:
|
||||||
|
"""
|
||||||
|
The list of users related with the department.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.multiple_related_users([self])
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
return cls.objects.all().order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class StudentGroup(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A student group.
|
A student group.
|
||||||
|
|
||||||
|
@ -56,6 +137,7 @@ class StudentGroup(models.Model):
|
||||||
id: uuid.UUID = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False, max_length=36)
|
id: uuid.UUID = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False, max_length=36)
|
||||||
name: str = models.CharField(max_length=128)
|
name: str = models.CharField(max_length=128)
|
||||||
|
|
||||||
|
department = models.ForeignKey(to=Department, on_delete=models.CASCADE, related_name="student_groups")
|
||||||
students = models.ManyToManyField(to=get_user_model(), blank=True, related_name="student_groups")
|
students = models.ManyToManyField(to=get_user_model(), blank=True, related_name="student_groups")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
@ -64,8 +146,24 @@ class StudentGroup(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class TeachingUnit(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the groups where the user is
|
||||||
|
Q(students=user) |
|
||||||
|
# get all the groups where the department is managed by the user
|
||||||
|
Q(department=user.managing_departments)
|
||||||
|
# TODO: prof ? rôle créateur du groupe ?
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingUnit(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A teaching unit.
|
A teaching unit.
|
||||||
|
|
||||||
|
@ -90,8 +188,21 @@ class TeachingUnit(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class StudentCard(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the units with a common department with the user
|
||||||
|
Q(department__in=user.related_departments)
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCard(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A student card.
|
A student card.
|
||||||
|
|
||||||
|
@ -106,8 +217,23 @@ class StudentCard(models.Model):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} id={str(self.id)[:8]} owner={self.owner.username!r}>"
|
return f"<{self.__class__.__name__} id={str(self.id)[:8]} owner={self.owner.username!r}>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class TeachingSession(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the cards that are owned by the user
|
||||||
|
Q(owner=user) |
|
||||||
|
# get all the cards where the owner is studying in a department where the user is a manager
|
||||||
|
Q(owner__studying_departments__managers=user)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class TeachingSession(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A session of a teaching unit.
|
A session of a teaching unit.
|
||||||
|
|
||||||
|
@ -136,8 +262,27 @@ class TeachingSession(models.Model):
|
||||||
def end(self) -> datetime:
|
def end(self) -> datetime:
|
||||||
return self.start + self.duration
|
return self.start + self.duration
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class Attendance(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the sessions where the user is a teacher
|
||||||
|
Q(teacher=user) |
|
||||||
|
# get all the sessions where the user is in the group
|
||||||
|
Q(group__students=user) |
|
||||||
|
# get all the sessions where the user is managing the unit
|
||||||
|
Q(unit__managers=user) |
|
||||||
|
# get all the sessions where the user is managing the department
|
||||||
|
Q(unit__department__managers=user)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class Attendance(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A student attendance to a session.
|
A student attendance to a session.
|
||||||
|
|
||||||
|
@ -167,8 +312,27 @@ class Attendance(models.Model):
|
||||||
f">"
|
f">"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class Absence(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the session where the user was the teacher
|
||||||
|
Q(session__teacher=user) |
|
||||||
|
# get all the session where the user was the student
|
||||||
|
Q(student=user) |
|
||||||
|
# get all the sessions where the user is managing the unit
|
||||||
|
Q(session__unit__managers=user) |
|
||||||
|
# get all the sessions where the user is managing the department
|
||||||
|
Q(session__unit__department__managers=user)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class Absence(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
A student justified absence to a session.
|
A student justified absence to a session.
|
||||||
|
|
||||||
|
@ -193,8 +357,27 @@ class Absence(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"[{str(self.id)[:8]}] {self.student}"
|
return f"[{str(self.id)[:8]}] {self.student}"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
class AbsenceAttachment(models.Model):
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the absence where the user was the teacher
|
||||||
|
Q(session__teacher=user) |
|
||||||
|
# get all the absence where the user was the student
|
||||||
|
Q(student=user) |
|
||||||
|
# get all the absences where the user is managing the unit
|
||||||
|
Q(session__unit__managers=user) |
|
||||||
|
# get all the absences where the user is managing the department
|
||||||
|
Q(session__unit__department__managers=user)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
||||||
|
|
||||||
|
class AbsenceAttachment(models.Model, ModelApiMixin):
|
||||||
"""
|
"""
|
||||||
An attachment to a student justified absence.
|
An attachment to a student justified absence.
|
||||||
|
|
||||||
|
@ -208,3 +391,22 @@ class AbsenceAttachment(models.Model):
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<{self.__class__.__name__} id={str(self.id)[:8]} content={self.content!r}>"
|
return f"<{self.__class__.__name__} id={str(self.id)[:8]} content={self.content!r}>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def all_visible_to(cls, user: "User") -> QuerySet["User"]:
|
||||||
|
if user.is_superuser:
|
||||||
|
queryset = cls.objects.all()
|
||||||
|
|
||||||
|
else:
|
||||||
|
queryset = cls.objects.filter(
|
||||||
|
# get all the absence attachments where the user was the teacher
|
||||||
|
Q(absence__session__teacher=user) |
|
||||||
|
# get all the absence attachments where the user was the student
|
||||||
|
Q(absence__student=user) |
|
||||||
|
# get all the absence attachments where the user is managing the unit
|
||||||
|
Q(absence__session__unit__managers=user) |
|
||||||
|
# get all the absence attachments where the user is managing the department
|
||||||
|
Q(absence__session__unit__department__managers=user)
|
||||||
|
).distinct()
|
||||||
|
|
||||||
|
return queryset.order_by("pk")
|
||||||
|
|
|
@ -151,7 +151,21 @@ REST_FRAMEWORK = {
|
||||||
# or allow read-only access for unauthenticated users.
|
# or allow read-only access for unauthenticated users.
|
||||||
'DEFAULT_PERMISSION_CLASSES': [
|
'DEFAULT_PERMISSION_CLASSES': [
|
||||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
||||||
]
|
],
|
||||||
|
|
||||||
|
# Default rate limiting
|
||||||
|
'DEFAULT_THROTTLE_CLASSES': [
|
||||||
|
'rest_framework.throttling.AnonRateThrottle',
|
||||||
|
'rest_framework.throttling.UserRateThrottle',
|
||||||
|
],
|
||||||
|
'DEFAULT_THROTTLE_RATES': {
|
||||||
|
'anon': '2/min',
|
||||||
|
'user': '15/min'
|
||||||
|
},
|
||||||
|
|
||||||
|
# Allow up to 30 elements per page
|
||||||
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
|
||||||
|
'PAGE_SIZE': 30
|
||||||
}
|
}
|
||||||
|
|
||||||
# User model
|
# User model
|
||||||
|
|
|
@ -14,10 +14,12 @@ Including another URLconf
|
||||||
1. Import the include() function: from django.urls import include, path
|
1. Import the include() function: from django.urls import include, path
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
|
import debug_toolbar
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include, re_path
|
from django.urls import path, re_path, include
|
||||||
from django.views.static import serve
|
from django.views.static import serve
|
||||||
|
|
||||||
|
from Palto.Palto.api import urls as api_urls
|
||||||
from Palto import settings
|
from Palto import settings
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,11 +28,11 @@ urlpatterns = [
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
# API
|
# API
|
||||||
path('api/', include('rest_framework.urls')), # API REST
|
path('api/', include(api_urls)), # Api REST
|
||||||
|
|
||||||
# Debug
|
# Debug
|
||||||
path('admin/', admin.site.urls), # Admin page
|
path('admin/', admin.site.urls), # Admin page
|
||||||
path("__debug__/", include("debug_toolbar.urls")), # Debug toolbar
|
path("__debug__/", include(debug_toolbar.urls)), # Debug toolbar
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
django
|
django
|
||||||
djangorestframework
|
djangorestframework
|
||||||
django-filter
|
|
||||||
django-debug-toolbar
|
django-debug-toolbar
|
||||||
django-extensions
|
django-extensions
|
||||||
Werkzeug
|
Werkzeug
|
||||||
|
|
Loading…
Reference in a new issue