Skip to content

Commit 0d9a04d

Browse files
committed
APP-35: auxiliary user table and booking endpoints
1 parent ddabd11 commit 0d9a04d

File tree

11 files changed

+107
-84
lines changed

11 files changed

+107
-84
lines changed

Diff for: backend/api/admin.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
from django.contrib import admin
2+
from django.contrib.auth.admin import UserAdmin
3+
from django.contrib.auth.models import User
24

3-
from .models.User import User
5+
from .models.Account import Account
46
from .models.Booking import Booking
57

68

7-
class UserAdmin(admin.ModelAdmin):
8-
list = ('id', 'email', 'travel_points', 'username', 'password', 'created_at')
9+
class AccountInline(admin.StackedInline):
10+
model = Account
11+
can_delete = False
12+
verbose_name_plural = 'Accounts'
913

1014

15+
class MyUserAdmin(UserAdmin):
16+
inlines = (AccountInline, )
17+
18+
19+
admin.site.unregister(User)
20+
admin.site.register(User, MyUserAdmin)
1121
admin.site.register(Booking)
12-
admin.site.register(User)

Diff for: backend/api/models/Account.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from django.contrib.auth.models import User
2+
from django.db import models
3+
from django.db.models import IntegerField
4+
5+
6+
class Account(models.Model):
7+
user = models.OneToOneField(User, on_delete=models.CASCADE)
8+
travel_points = IntegerField()
9+
10+
def _str_(self):
11+
return self.user.username

Diff for: backend/api/models/Booking.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
from django.contrib.auth.models import User
12
from django.db import models
2-
from django.db.models import IntegerField, CharField, FloatField, DateTimeField, TextChoices, ForeignKey
3-
from .User import User
3+
from django.db.models import (CharField, DateTimeField, FloatField, ForeignKey,
4+
IntegerField, TextChoices)
45

56

67
class Booking(models.Model):
@@ -12,16 +13,18 @@ class BookingStatus(TextChoices):
1213
CANCELLED = 'CA', ('Cancelled')
1314
PAST = 'PA', ('Past')
1415

15-
id = IntegerField(primary_key=True)
1616
stripe_id = CharField(max_length=200)
17+
hotel_id = CharField(max_length=200, null=True)
18+
room_id = CharField(max_length=20, null=True)
1719
amount_paid = FloatField()
1820
guest_count = IntegerField()
1921
points_earned = IntegerField()
20-
status = CharField(max_length=2, choices=BookingStatus.choices, default=BookingStatus.PENDING)
21-
user_id = ForeignKey(User, on_delete=models.CASCADE)
22+
status = CharField(
23+
max_length=2, choices=BookingStatus.choices, default=BookingStatus.PENDING)
24+
user = ForeignKey(User, on_delete=models.CASCADE)
2225
start_date = DateTimeField()
2326
end_date = DateTimeField()
2427
created_at = DateTimeField()
2528

2629
def _str_(self):
27-
return self.title
30+
return self.hotel_id

Diff for: backend/api/models/User.py

-14
This file was deleted.

Diff for: backend/api/models/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import Account, Booking

Diff for: backend/api/modules/amadeus.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from amadeus import Client, ResponseError
1+
from amadeus import Client, ResponseError # type: ignore
2+
23
from app import config
34

45
amadeus = Client(

Diff for: backend/api/modules/hotelbeds.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import hashlib
22
import time
33

4-
from app import config
54
from requests import Session
65

6+
from app import config
7+
78

89
def generate_signature(api_key: str, secret: str) -> str:
910
"""Generates a signature for the Hotelbeds API.

Diff for: backend/api/serializers.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1+
from django.contrib.auth.models import User
12
from rest_framework import serializers
23

3-
from .models.User import User
44
from .models.Booking import Booking
55

66

77
class UserSerializer(serializers.ModelSerializer):
88
class Meta:
9+
fields = ('id', 'username', 'email', 'first_name',
10+
'last_name', 'date_joined', 'last_login')
911
model = User
1012

1113

1214
class BookingSerializer(serializers.ModelSerializer):
15+
# TODO: setup permissions
1316
class Meta:
17+
fields = ('id',
18+
'stripe_id',
19+
'hotel_id',
20+
'room_id',
21+
'amount_paid',
22+
'guest_count',
23+
'points_earned',
24+
'status',
25+
'user',
26+
'start_date',
27+
'end_date',
28+
'created_at')
1429
model = Booking

Diff for: backend/api/urls.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
from . import views
2020

2121
router = routers.DefaultRouter()
22-
# router.register(r'users', views.UserView, 'User')
22+
router.register(r'booking', views.BookingView, 'Booking')
23+
router.register(r'user', views.UserView, 'User')
24+
2325

2426
urlpatterns = [
2527
path('csrf', views.CSRFGeneratorView.as_view()),
26-
path('user/me', views.UserView.as_view()),
2728
path('', include(router.urls)),
2829
]

Diff for: backend/api/views.py

+38-24
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1+
from django.contrib.auth.models import User
12
from django.utils.decorators import method_decorator
23
from django.views.decorators.csrf import ensure_csrf_cookie
34
from rest_framework import permissions, views, viewsets
4-
from rest_framework.decorators import api_view
5+
from rest_framework.permissions import IsAuthenticated
56
from rest_framework.request import Request
67
from rest_framework.response import Response
78

8-
from .models.User import User
99
from .models.Booking import Booking
10-
from .serializers import UserSerializer
11-
from .serializers import BookingSerializer
10+
from .serializers import BookingSerializer, UserSerializer
1211

1312

14-
class UserView(viewsets.ModelViewSet):
15-
serializer_class = UserSerializer
16-
queryset = User.objects.all()
17-
18-
19-
class BookingView(viewsets.ModelViewSet):
20-
serializer_class = BookingSerializer
21-
queryset = Booking.objects.all()
22-
2313
@method_decorator(ensure_csrf_cookie, name='dispatch')
2414
class CSRFGeneratorView(views.APIView):
2515
permissions_classes = [permissions.AllowAny]
@@ -28,17 +18,41 @@ def get(self, request: Request, format=None):
2818
return Response({'success': True})
2919

3020

31-
class UserView(views.APIView):
32-
# TODO: figure out why this doesn't work
33-
permissions_classes = [permissions.IsAuthenticated]
21+
class BookingView(viewsets.ModelViewSet):
22+
serializer_class = BookingSerializer
23+
permission_classes = [IsAuthenticated]
3424

35-
def get(self, request: Request, format=None):
36-
user = request.user
25+
def get_queryset(self):
26+
"""
27+
This view should return a list of all the purchases
28+
for the currently authenticated user.
29+
"""
30+
return Booking.objects.filter(user=self.request.user)
31+
32+
def get_object(self):
33+
"""Get a single booking object by pk
34+
35+
Returns:
36+
_type_: _description_
37+
"""
38+
pk = self.kwargs.get('pk')
39+
40+
if pk is not None:
41+
return Booking.objects.get(id=pk, user=self.request.user)
42+
43+
return super().get_object()
44+
45+
46+
class UserView(viewsets.ModelViewSet):
47+
queryset = User.objects.all()
48+
serializer_class = UserSerializer
49+
permission_classes = [IsAuthenticated]
50+
51+
def get_object(self):
52+
pk = self.kwargs.get('pk')
3753

38-
if not user.is_authenticated:
39-
return Response({'error': 'User not authenticated'}, status=401)
54+
if pk == "me":
55+
return self.request.user
4056

41-
return Response({
42-
'username': user.username,
43-
'email': user.email,
44-
})
57+
# TODO: only allow admins to list all other users
58+
return super().get_object()

Diff for: database.dbml

+12-31
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
Table User {
2-
id integer
3-
email varchar(200)
4-
travel_points integer
5-
username varchar(60)
6-
password varchar(200)
7-
created_at timestamp
1+
// from djando.contrib.auth.models import User
2+
Table User {
3+
id int [pk, increment]
4+
first_name varchar(200)
5+
last_name varchar(200)
6+
email varchar(200) [unique]
87
}
98

10-
Enum PropertyType {
11-
Hotel
12-
Motel
13-
Cabin
14-
Condo
15-
Villa
16-
Apartment
17-
Resort
9+
// from api.models import Account
10+
Table Account {
11+
user_id int [ref: > User.id]
12+
travel_points integer
1813
}
1914

2015
Enum BookingStatus {
@@ -24,6 +19,7 @@ Enum BookingStatus {
2419
Past
2520
}
2621

22+
// from api.models import Booking
2723
Table Booking {
2824
id int [pk, increment]
2925
stripe_id varchar(200)
@@ -35,19 +31,4 @@ Table Booking {
3531
start_date date
3632
end_date date
3733
created_at timestamp
38-
}
39-
40-
Table Review {
41-
id int [pk, increment]
42-
user_id int [ref: > User.id]
43-
rating int
44-
comment varchar(200)
45-
created_at timestamp
46-
}
47-
48-
Table Image {
49-
id int [pk, increment]
50-
url varchar(200)
51-
created_at timestamp
52-
}
53-
34+
}

0 commit comments

Comments
 (0)