Skip to content

Commit

Permalink
Merge pull request #85 from SELab-2/backend_changes
Browse files Browse the repository at this point in the history
Backend changes
  • Loading branch information
LGDTimtou authored Mar 21, 2024
2 parents 68abde3 + 5482180 commit b48b8f8
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 116 deletions.
5 changes: 4 additions & 1 deletion api/models/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Indiening(models.Model):
indiening_id = models.AutoField(primary_key=True)
groep = models.ForeignKey("Groep", on_delete=models.CASCADE)
tijdstip = models.DateTimeField(auto_now_add=True)
status = models.BooleanField()

def __str__(self):
return str(self.indiening_id)
Expand All @@ -59,7 +60,9 @@ class IndieningBestand(models.Model):
"""

indiening_bestand_id = models.AutoField(primary_key=True)
indiening = models.ForeignKey("Indiening", on_delete=models.CASCADE)
indiening = models.ForeignKey(
Indiening, related_name="indiening_bestanden", on_delete=models.CASCADE
)
bestand = models.FileField(upload_to=upload_to)

def __str__(self):
Expand Down
5 changes: 4 additions & 1 deletion api/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ class Project(models.Model):
beschrijving = models.TextField()
opgave_bestand = models.FileField(upload_to=upload_to)
vak = models.ForeignKey(Vak, on_delete=models.CASCADE)
deadline = models.DateTimeField(null=True)
deadline = models.DateTimeField(null=True, blank=True)
extra_deadline = models.DateTimeField(null=True, blank=True)
max_score = models.IntegerField(default=20)
zichtbaar = models.BooleanField(default=True, blank=True)
gearchiveerd = models.BooleanField(default=False, blank=True)
# indiening restricties

def __str__(self):
Expand Down
24 changes: 22 additions & 2 deletions api/serializers/gebruiker.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from rest_framework import serializers
from api.models.gebruiker import Gebruiker
from api.models.vak import Vak


class GebruikerSerializer(serializers.ModelSerializer):
Expand All @@ -16,9 +17,13 @@ class GebruikerSerializer(serializers.ModelSerializer):
update(self, instance, validated_data): Werkt een bestaande gebruiker bij in de database.
"""

first_name = serializers.CharField(source="user.first_name", read_only=True)
last_name = serializers.CharField(source="user.last_name", read_only=True)
email = serializers.EmailField(source="user.email", read_only=True)

class Meta:
model = Gebruiker
fields = "__all__"
fields = ["user", "is_lesgever", "first_name", "last_name", "email"]

def create(self, validated_data):
"""
Expand All @@ -40,6 +45,21 @@ def update(self, instance, validated_data):
Returns:
Gebruiker: De bijgewerkte gebruiker.
"""
instance.is_lesgever = validated_data.pop("is_lesgever")
is_lesgever = validated_data.pop("is_lesgever")
if instance.is_lesgever != is_lesgever:
validate_lesgever_change(instance)

instance.is_lesgever = is_lesgever
instance.save()
return instance


def validate_lesgever_change(instance):
if instance.is_lesgever and Vak.objects.filter(lesgevers=instance):
raise serializers.ValidationError(
f"De lesgever {instance} moet eerst verwijderd worden als lesgever in zijn huidige vakken"
)
elif not instance.is_lesgever and Vak.objects.filter(studenten=instance):
raise serializers.ValidationError(
f"De student {instance} moet eerst verwijderd worden als student in zijn huidige vakken"
)
15 changes: 6 additions & 9 deletions api/serializers/groep.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from rest_framework import serializers
from api.models.groep import Groep
from collections import Counter


class GroepSerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -75,21 +74,19 @@ def validate_students(students_data, project, current_group=None):
if current_group is not None:
groepen = groepen.exclude(groep_id=current_group.groep_id)

student_counts = Counter(students_data)
for student, count in student_counts.items():
if count > 1:
raise serializers.ValidationError(
f"Student {student} zit al in deze groep!"
)

for student in students_data:
if student.is_lesgever:
raise serializers.ValidationError(
"Alle gebruikers in 'studenten' moeten studenten zijn!"
)

if not project.vak.studenten.all().contains(student):
raise serializers.ValidationError(
f"Student {student} is geen student van het vak {project.vak}"
)

for groep in groepen:
if student in groep.studenten.all():
raise serializers.ValidationError(
f"Gebruiker {student} zit al in een andere groep voor dit project!"
f"Student {student} zit al in een andere groep voor dit project!"
)
20 changes: 11 additions & 9 deletions api/serializers/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,33 @@
from api.models.indiening import Indiening, IndieningBestand


class IndieningSerializer(serializers.ModelSerializer):
class IndieningBestandSerializer(serializers.ModelSerializer):
"""
Serializer voor het serialiseren en deserialiseren van Indiening objecten.
Serializer voor het serialiseren en deserialiseren van IndieningBestand objecten.
Fields:
Meta.model (Indiening): Het model waarop de serializer is gebaseerd.
Meta.model (IndieningBestand): Het model waarop de serializer is gebaseerd.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier worden alle velden opgenomen.
"""

class Meta:
model = Indiening
model = IndieningBestand
fields = "__all__"


class IndieningBestandSerializer(serializers.ModelSerializer):
class IndieningSerializer(serializers.ModelSerializer):
"""
Serializer voor het serialiseren en deserialiseren van IndieningBestand objecten.
Serializer voor het serialiseren en deserialiseren van Indiening objecten.
Fields:
Meta.model (IndieningBestand): Het model waarop de serializer is gebaseerd.
Meta.model (Indiening): Het model waarop de serializer is gebaseerd.
Meta.fields (tuple): De velden die moeten worden opgenomen in de serializer. Hier worden alle velden opgenomen.
"""

indiening_bestanden = IndieningBestandSerializer(many=True, read_only=True)

class Meta:
model = IndieningBestand
fields = "__all__"
model = Indiening
fields = ["indiening_id", "groep", "tijdstip", "status", "indiening_bestanden"]
15 changes: 12 additions & 3 deletions api/serializers/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ def create(self, validated_data):
Project: Het aangemaakte project.
"""
deadline = validated_data.pop("deadline")
validate_deadline(deadline)
extra_deadline = validated_data.pop("extra_deadline")
validate_deadlines(deadline, extra_deadline)

project = Project.objects.create(**validated_data)
project.deadline = deadline
project.extra_deadline = extra_deadline
project.save()
return project

Expand All @@ -47,15 +49,17 @@ def update(self, instance, validated_data):
Project: Het bijgewerkte project.
"""
deadline = validated_data.pop("deadline")
validate_deadline(deadline)
extra_deadline = validated_data.pop("extra_deadline")
validate_deadlines(deadline, extra_deadline)

super().update(instance=instance, validated_data=validated_data)
instance.deadline = deadline
instance.extra_deadline = extra_deadline
instance.save()
return instance


def validate_deadline(deadline):
def validate_deadlines(deadline, extra_deadline):
"""
Controleert of de opgegeven deadline in de toekomst ligt.
Expand All @@ -67,3 +71,8 @@ def validate_deadline(deadline):
"""
if deadline <= timezone.now():
raise serializers.ValidationError("Deadline moet in de toekomst liggen")

if extra_deadline <= deadline:
raise serializers.ValidationError(
"Extra deadline moet na de eerste deadline liggen"
)
5 changes: 5 additions & 0 deletions api/tests/factories/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class Meta:
fake.date_time_between(start_date="+1d", end_date="+30d")
)
)
status = factory.Faker("boolean")

indiening_bestanden = factory.RelatedFactory(
"api.tests.factories.indiening.IndieningBestandFactory", "indiening"
)


class IndieningBestandFactory(DjangoModelFactory):
Expand Down
7 changes: 7 additions & 0 deletions api/tests/factories/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@ class Meta:
fake.date_time_between(start_date="+1d", end_date="+30d")
)
)
extra_deadline = factory.LazyFunction(
lambda: timezone.make_aware(
fake.date_time_between(start_date="+30d", end_date="+40d")
)
)
max_score = factory.Faker("random_int", min=10, max=100)
zichtbaar = factory.Faker('boolean')
gearchiveerd = factory.Faker('boolean')
14 changes: 6 additions & 8 deletions api/tests/models/test_indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@ def test_groep(self):

def test_tijdstip(self):
self.assertIsNotNone(self.indiening.tijdstip)

def test_indiening_bestand(self):
self.assertEqual(self.indiening.indieningbestand_set.count(), 0)

def test_indiening_bestand_add(self):
IndieningBestandFactory.create(indiening=self.indiening)
self.assertEqual(self.indiening.indieningbestand_set.count(), 1)


def test_status(self):
self.assertIsNotNone(self.indiening.status)

def test_indiening_bestanden(self):
self.assertEqual(self.indiening.indiening_bestanden.count(), 1)

class IndieningBestandModelTest(TestCase):
def setUp(self):
Expand Down
15 changes: 15 additions & 0 deletions api/tests/models/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,18 @@ def test_project_vak(self):

def test_project_max_score(self):
self.assertTrue(10 <= self.project.max_score <= 100)

def test_project_zichtbaar(self):
self.assertIsNotNone(self.project.zichtbaar)

def test_project_gearchiveerd(self):
self.assertIsNotNone(self.project.gearchiveerd)

def test_project_deadline(self):
self.assertIsNotNone(self.project.deadline)

def test_project_extra_deadline(self):
self.assertIsNotNone(self.project.extra_deadline)

def test_project_opgave_bestand(self):
self.assertEqual(self.project.opgave_bestand.read(), b"file content")
17 changes: 1 addition & 16 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,7 @@
from .views.gebruiker import gebruiker_list, gebruiker_detail
from .views.vak import vak_list, vak_detail
from .views.project import project_list, project_detail
from .views.indiening import (
indiening_list,
indiening_detail,
indiening_bestand_list,
indiening_bestand_detail,
)
from .views.indiening import indiening_list, indiening_detail
from .views.score import score_list, score_detail
from .views.groep import groep_list, groep_detail

Expand All @@ -50,16 +45,6 @@
path("api/projecten/<int:id>/", project_detail, name="project_detail"),
path("api/indieningen/", indiening_list, name="indiening_list"),
path("api/indieningen/<int:id>/", indiening_detail, name="indiening_detail"),
path(
"api/indiening_bestanden/",
indiening_bestand_list,
name="indiening_bestand_list",
),
path(
"api/indiening_bestanden/<int:id>/",
indiening_bestand_detail,
name="indiening_bestand_detail",
),
path("api/scores/", score_list, name="score_list"),
path("api/scores/<int:id>/", score_detail, name="score_detail"),
path("api/groepen/", groep_list, name="groep_list"),
Expand Down
1 change: 0 additions & 1 deletion api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"vakken": "/api/vakken",
"groepen": "/api/groepen",
"indieningen": "/api/indieningen",
"indiening_bestanden": "/api/indiening_bestanden",
"scores": "api/scores",
"projecten": "api/projecten",
}
Expand Down
66 changes: 1 addition & 65 deletions api/views/indiening.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from api.models.indiening import Indiening, IndieningBestand
from api.models.groep import Groep
from api.serializers.indiening import IndieningSerializer, IndieningBestandSerializer
from api.serializers.indiening import IndieningSerializer
from api.utils import is_lesgever, contains


Expand Down Expand Up @@ -95,67 +95,3 @@ def indiening_detail(request, id, format=None):
indiening.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(status=status.HTTP_403_FORBIDDEN)


@api_view(["GET"])
def indiening_bestand_list(request, format=None):
"""
Een view om een lijst van indieningbestanden op te halen (GET).
GET:
Als de gebruiker een lesgever is, worden alle indieningbestanden opgehaald.
Als de gebruiker geen lesgever is, worden alleen de indieningbestanden opgehaald
van de ingelogde gebruiker.
Optionele query parameters:
indiening (int): Filtert indieningbestanden op basis van indiening-ID.
Returns:
Response: Een lijst van indieningbestandgegevens.
"""
if request.method == "GET":
if is_lesgever(request.user):
indieningen_bestanden = IndieningBestand.objects.all()
else:
groepen = Groep.objects.filter(studenten=request.user.id)
indieningen = Indiening.objects.filter(groep__in=groepen)
indieningen_bestanden = IndieningBestand.objects.filter(
indiening__in=indieningen
)

if "indiening" in request.GET:
try:
indiening = eval(request.GET.get("indiening"))
indieningen_bestanden = indieningen_bestanden.filter(
indiening=indiening
)
except NameError:
return Response(status=status.HTTP_400_BAD_REQUEST)

serializer = IndieningBestandSerializer(indieningen_bestanden, many=True)
return Response(serializer.data)


@api_view(["GET"])
def indiening_bestand_detail(request, id, format=None):
"""
Een view om de gegevens van een specifiek indieningbestand op te halen (GET).
Args:
id (int): De primaire sleutel van het indieningbestand.
Returns:
Response: Gegevens van het indieningbestand of een foutmelding als
het indieningbestand niet bestaat of als er een ongeautoriseerde toegang is.
"""
try:
indiening_bestand = IndieningBestand.objects.get(pk=id)
except IndieningBestand.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)

if request.method == "GET":
if is_lesgever(request.user) or contains(
indiening_bestand.indiening.groep.studenten, request.user
):
serializer = IndieningBestandSerializer(indiening_bestand)
return Response(serializer.data)
return Response(status=status.HTTP_403_FORBIDDEN)
2 changes: 1 addition & 1 deletion api/views/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def project_list(request, format=None):
projects = Project.objects.all()
else:
vakken = Vak.objects.filter(studenten=request.user.id)
projects = Project.objects.filter(vak__in=vakken)
projects = Project.objects.filter(vak__in=vakken).filter(zichtbaar=True)

if "vak" in request.GET:
try:
Expand Down

0 comments on commit b48b8f8

Please sign in to comment.