Skip to content

Commit 9f60e73

Browse files
committed
Basic api draft.
1 parent e750a3a commit 9f60e73

9 files changed

Lines changed: 233 additions & 2 deletions

File tree

backendapi/admin.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
from django.contrib import admin
2+
from .models import Attendant
23

3-
# Register your models here.
4+
5+
class AttendantAdmin(admin.ModelAdmin):
6+
list_display = ["first_name", "last_name", "email", "phone_number"]
7+
8+
9+
admin.site.register(Attendant, AttendantAdmin)

backendapi/exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from rest_framework.exceptions import APIException
2+
3+
# write your custm exceptions here if we need it later.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Generated by Django 5.1.3 on 2024-11-25 08:50
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = []
11+
12+
operations = [
13+
migrations.CreateModel(
14+
name="Attendant",
15+
fields=[
16+
(
17+
"id",
18+
models.BigAutoField(
19+
auto_created=True,
20+
primary_key=True,
21+
serialize=False,
22+
verbose_name="ID",
23+
),
24+
),
25+
("first_name", models.CharField(max_length=30)),
26+
("last_name", models.CharField(max_length=30)),
27+
("email", models.EmailField(max_length=100)),
28+
("phone_number", models.CharField(max_length=12)),
29+
],
30+
),
31+
]

backendapi/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
11
from django.db import models
2+
from rest_framework import serializers
3+
from django.contrib.auth.models import User
4+
5+
6+
# this is the Attendant model, im unsure if we need more data? Maby date of birth? => 18 years maby?
7+
class Attendant(models.Model):
8+
first_name = models.CharField(max_length=30)
9+
last_name = models.CharField(max_length=30)
10+
email = models.EmailField(max_length=100)
11+
phone_number = models.CharField(max_length=12)
12+
13+
def __str__(self):
14+
return f"{self.first_name} {self.last_name}"
15+
216

317
# Create your models here.

backendapi/serializers.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import re
2+
from rest_framework import serializers
3+
from django.conf import settings
4+
from .models import Attendant
5+
6+
# Serializer for the Attendant model: handles validation, serialization, and desersialization of data.
7+
# Change the model later depending on requirements. Please tell me what, and il remake the model later to fit requirements.
8+
9+
10+
class AttendantAdmin(serializers.ModelSerializer): # defined a serialiser class
11+
first_name = serializers.CharField(
12+
label=("First Name* "), # Labels for the field
13+
required=True, # This makes the fields required.
14+
max_length=100,
15+
style={
16+
"input_type": "text",
17+
"autofocus": False,
18+
"autocomplete": "off",
19+
"required": True,
20+
},
21+
error_messages={
22+
"required": "This field is required.",
23+
"blank": "First Name is required.",
24+
},
25+
)
26+
27+
last_name = serializers.CharField(
28+
label=("Last Name* "), # Label for the field
29+
required=True, # This makes the fields required.
30+
max_length=100,
31+
style={
32+
"input_type": "text",
33+
"autofocus": False,
34+
"autocomplete": "off",
35+
"required": True,
36+
},
37+
error_messages={
38+
"required": "This field is required.",
39+
"blank": "Last Name is required.",
40+
"invalid": "Last Name can only contain characters.",
41+
},
42+
)
43+
44+
email = serializers.EmailField(
45+
label=("Email* "), # Label for the field
46+
required=True, # Field is required
47+
max_length=100,
48+
style={
49+
"input_type": "email",
50+
"autofocus": False,
51+
"autocomplete": "off",
52+
"required": True,
53+
},
54+
error_messages={
55+
"required": "This field is required.",
56+
"blank": "Email is required.",
57+
},
58+
)
59+
phone_number = serializers.CharField(
60+
label="Phone Number* ", # Label for the field
61+
max_length=14,
62+
min_length=10,
63+
required=True, # Field is required
64+
error_messages={
65+
"required": "This field is required .",
66+
"blank": "Phone number is required.",
67+
},
68+
)
69+
70+
class Meta:
71+
model = Attendant
72+
fields = ["first_name", "last_name", "email", "phone_number"]
73+
74+
75+
def validate_first_name(value):
76+
# Check if the first name contains only characters or letters with spaces and letters from a-Z
77+
if not re.match(r"^[a-zA-Zå-öÅ-Ö ]*$", value):
78+
raise serializers.ValidationError(
79+
"First Name can only contain letters and spaces."
80+
)
81+
82+
83+
def validate_last_name(value):
84+
# Check if the first name contains only characters
85+
if not re.match(r"^[a-zA-Zå-öÅ-Ö ]*$", value):
86+
raise serializers.ValidationError(
87+
"Last Name can only contain letters and spaces."
88+
)

backendapi/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66

77
urlpatterns = [
88
path("nfctag/<hex:tag>", views.scanned),
9+
path("test", views.api_get, name="api_get"),
910
]

backendapi/views.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
from django.views.decorators.http import require_POST
44
from django.views.decorators.cache import never_cache
55
from django.http import JsonResponse
6-
76
from database.models import Attendant
87

8+
from rest_framework.decorators import api_view
9+
from rest_framework.response import Response
10+
from rest_framework import status
11+
from backendapi import exceptions
12+
from .serializers import AttendantAdmin
13+
914

1015
@csrf_exempt
1116
@require_POST
@@ -18,3 +23,83 @@ def scanned(request, tag: bytes):
1823

1924
except Attendant.DoesNotExist:
2025
return JsonResponse({"error": "No such tag", "valid": False}, status=404)
26+
27+
28+
@api_view(["GET", "POST", "PUT", "PATCH", "DELETE"])
29+
def api_get(request, pk=None):
30+
if request.method == "GET":
31+
# If there's no 'pk' parameter, return all attendants
32+
if pk is None:
33+
attendants = Attendant.objects.all()
34+
serializer = AttendantAdmin(attendants, many=True)
35+
return Response(serializer.data, status=status.HTTP_200_OK)
36+
# Otherwise, return a single attendant
37+
try:
38+
attendant = Attendant.objects.get(pk=pk)
39+
serializer = AttendantAdmin(attendant)
40+
return Response(serializer.data, status=status.HTTP_200_OK)
41+
except Attendant.DoesNotExist:
42+
return Response(
43+
{"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND
44+
)
45+
46+
elif request.method == "POST":
47+
# Create a new attendant
48+
serializer = AttendantAdmin(data=request.data)
49+
if serializer.is_valid():
50+
serializer.save() # Save the new attendant to the database
51+
return Response(serializer.data, status=status.HTTP_201_CREATED)
52+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
53+
54+
elif request.method == "PUT":
55+
# Full update of an existing attendant
56+
try:
57+
attendant = Attendant.objects.get(pk=pk)
58+
except Attendant.DoesNotExist:
59+
return Response(
60+
{"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND
61+
)
62+
63+
serializer = AttendantAdmin(attendant, data=request.data)
64+
if serializer.is_valid():
65+
serializer.save()
66+
return Response(serializer.data, status=status.HTTP_200_OK)
67+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
68+
69+
elif request.method == "PATCH":
70+
# Partial update of an existing attendant
71+
try:
72+
attendant = Attendant.objects.get(pk=pk)
73+
except Attendant.DoesNotExist:
74+
return Response(
75+
{"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND
76+
)
77+
78+
serializer = AttendantAdmin(attendant, data=request.data, partial=True)
79+
if serializer.is_valid():
80+
serializer.save()
81+
return Response(serializer.data, status=status.HTTP_200_OK)
82+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
83+
84+
elif request.method == "DELETE":
85+
# Delete an existing attendant
86+
try:
87+
attendant = Attendant.objects.get(pk=pk)
88+
except Attendant.DoesNotExist:
89+
return Response(
90+
{"detail": "Attendant not found."}, status=status.HTTP_404_NOT_FOUND
91+
)
92+
93+
attendant.delete()
94+
return Response(
95+
{"detail": "Attendant deleted successfully."},
96+
status=status.HTTP_204_NO_CONTENT,
97+
)
98+
99+
100+
"""
101+
def api_get(request):
102+
if request.method == "GET":
103+
return Response({"message": "GET request received"}, status=202)
104+
elif request.method == "POST":
105+
return Response({"message": "POST request received"}, status=405) """

config/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
# ---
4545
"database",
4646
"backendapi",
47+
"rest_framework",
4748
]
4849

4950
MIDDLEWARE = [

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@ Django[all]==5.1.3
22
django-urlconfchecks==0.11.0 # TODO: Add to CI
33
daphne==4.1.2
44
psycopg2-binary==2.9.10
5+
djangorestframework==3.15.2
6+

0 commit comments

Comments
 (0)