diff --git a/backendapi/admin.py b/backendapi/admin.py index 8c38f3f..ab8fb6b 100644 --- a/backendapi/admin.py +++ b/backendapi/admin.py @@ -1,3 +1,9 @@ from django.contrib import admin +from .models import Attendant -# Register your models here. + +class AttendantAdmin(admin.ModelAdmin): + list_display = ["first_name", "last_name", "email", "phone_number"] + + +admin.site.register(Attendant, AttendantAdmin) diff --git a/backendapi/exceptions.py b/backendapi/exceptions.py new file mode 100644 index 0000000..bec4070 --- /dev/null +++ b/backendapi/exceptions.py @@ -0,0 +1,3 @@ +from rest_framework.exceptions import APIException + +# write your custm exceptions here if we need it later. diff --git a/backendapi/migrations/0001_initial.py b/backendapi/migrations/0001_initial.py new file mode 100644 index 0000000..0df89ab --- /dev/null +++ b/backendapi/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 5.1.3 on 2024-11-25 08:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Attendant", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("first_name", models.CharField(max_length=30)), + ("last_name", models.CharField(max_length=30)), + ("email", models.EmailField(max_length=100)), + ("phone_number", models.CharField(max_length=12)), + ], + ), + ] diff --git a/backendapi/models.py b/backendapi/models.py index 71a8362..0e85128 100644 --- a/backendapi/models.py +++ b/backendapi/models.py @@ -1,3 +1,17 @@ from django.db import models +from rest_framework import serializers +from django.contrib.auth.models import User + + +# this is the Attendant model, im unsure if we need more data? Maby date of birth? => 18 years maby? +class Attendant(models.Model): + first_name = models.CharField(max_length=30) + last_name = models.CharField(max_length=30) + email = models.EmailField(max_length=100) + phone_number = models.CharField(max_length=12) + + def __str__(self): + return f"{self.first_name} {self.last_name}" + # Create your models here. diff --git a/backendapi/serializers.py b/backendapi/serializers.py new file mode 100644 index 0000000..852a20c --- /dev/null +++ b/backendapi/serializers.py @@ -0,0 +1,88 @@ +import re +from rest_framework import serializers +from django.conf import settings +from .models import Attendant + +# Serializer for the Attendant model: handles validation, serialization, and desersialization of data. +# Change the model later depending on requirements. Please tell me what, and il remake the model later to fit requirements. + + +class AttendantAdmin(serializers.ModelSerializer): # defined a serialiser class + first_name = serializers.CharField( + label=("First Name* "), # Labels for the field + required=True, # This makes the fields required. + max_length=100, + style={ + "input_type": "text", + "autofocus": False, + "autocomplete": "off", + "required": True, + }, + error_messages={ + "required": "This field is required.", + "blank": "First Name is required.", + }, + ) + + last_name = serializers.CharField( + label=("Last Name* "), # Label for the field + required=True, # This makes the fields required. + max_length=100, + style={ + "input_type": "text", + "autofocus": False, + "autocomplete": "off", + "required": True, + }, + error_messages={ + "required": "This field is required.", + "blank": "Last Name is required.", + "invalid": "Last Name can only contain characters.", + }, + ) + + email = serializers.EmailField( + label=("Email* "), # Label for the field + required=True, # Field is required + max_length=100, + style={ + "input_type": "email", + "autofocus": False, + "autocomplete": "off", + "required": True, + }, + error_messages={ + "required": "This field is required.", + "blank": "Email is required.", + }, + ) + phone_number = serializers.CharField( + label="Phone Number* ", # Label for the field + max_length=14, + min_length=10, + required=True, # Field is required + error_messages={ + "required": "This field is required .", + "blank": "Phone number is required.", + }, + ) + + class Meta: + model = Attendant + fields = ["first_name", "last_name", "email", "phone_number"] + + +def validate_first_name(value): + # Check if the first name contains only characters or letters with spaces and letters from a-Z + if not re.match(r"^[a-zA-Zå-öÅ-Ö ]*$", value): + raise serializers.ValidationError( + "First Name can only contain letters and spaces." + ) + + +def validate_last_name(value): + # Check if the first name contains only characters + if not re.match(r"^[a-zA-Zå-öÅ-Ö ]*$", value): + raise serializers.ValidationError( + "Last Name can only contain letters and spaces." + ) diff --git a/backendapi/urls.py b/backendapi/urls.py index 692238f..d78b803 100644 --- a/backendapi/urls.py +++ b/backendapi/urls.py @@ -6,4 +6,5 @@ urlpatterns = [ path("nfctag/", views.scanned), + path("test", views.api_get, name="api_get"), ] diff --git a/backendapi/views.py b/backendapi/views.py index 9222937..9894a8a 100644 --- a/backendapi/views.py +++ b/backendapi/views.py @@ -3,9 +3,14 @@ from django.views.decorators.http import require_POST from django.views.decorators.cache import never_cache from django.http import JsonResponse - from database.models import Attendant +from rest_framework.decorators import api_view +from rest_framework.response import Response +from rest_framework import status +from backendapi import exceptions +from .serializers import AttendantAdmin + @csrf_exempt @require_POST @@ -18,3 +23,83 @@ def scanned(request, tag: bytes): except Attendant.DoesNotExist: return JsonResponse({"error": "No such tag", "valid": False}, status=404) + + +@api_view(["GET", "POST", "PUT", "PATCH", "DELETE"]) +def api_get(request, pk=None): + if request.method == "GET": + # If there's no 'pk' parameter, return all attendants + if pk is None: + attendants = Attendant.objects.all() + serializer = AttendantAdmin(attendants, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + # Otherwise, return a single attendant + try: + attendant = Attendant.objects.get(pk=pk) + serializer = AttendantAdmin(attendant) + return Response(serializer.data, status=status.HTTP_200_OK) + except Attendant.DoesNotExist: + return Response( + {"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND + ) + + elif request.method == "POST": + # Create a new attendant + serializer = AttendantAdmin(data=request.data) + if serializer.is_valid(): + serializer.save() # Save the new attendant to the database + return Response(serializer.data, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == "PUT": + # Full update of an existing attendant + try: + attendant = Attendant.objects.get(pk=pk) + except Attendant.DoesNotExist: + return Response( + {"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND + ) + + serializer = AttendantAdmin(attendant, data=request.data) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == "PATCH": + # Partial update of an existing attendant + try: + attendant = Attendant.objects.get(pk=pk) + except Attendant.DoesNotExist: + return Response( + {"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND + ) + + serializer = AttendantAdmin(attendant, data=request.data, partial=True) + if serializer.is_valid(): + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + elif request.method == "DELETE": + # Delete an existing attendant + try: + attendant = Attendant.objects.get(pk=pk) + except Attendant.DoesNotExist: + return Response( + {"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND + ) + + attendant.delete() + return Response( + {"detail": "Attendant deleted successfully."}, + status=status.HTTP_204_NO_CONTENT, + ) + + +""" +def api_get(request): + if request.method == "GET": + return Response({"message": "GET request received"}, status=202) + elif request.method == "POST": + return Response({"message": "POST request received"}, status=405) """ diff --git a/config/settings.py b/config/settings.py index 0764513..0461969 100644 --- a/config/settings.py +++ b/config/settings.py @@ -44,6 +44,7 @@ # --- "database", "backendapi", + "rest_framework", ] MIDDLEWARE = [ diff --git a/requirements.txt b/requirements.txt index edb6592..dfdad0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,5 @@ Django[all]==5.1.3 django-urlconfchecks==0.11.0 # TODO: Add to CI daphne==4.1.2 psycopg2-binary==2.9.10 +djangorestframework==3.15.2 +