From 53c9e768fae99045a2fceab9cd3a6782336d6ad0 Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:15:05 -0800 Subject: [PATCH 01/12] add save list --- .../user/migrations/0004_bidder_saved_list.py | 18 ++++++++ backend/user/models.py | 2 + backend/vehicle/urls.py | 8 +++- backend/vehicle/views.py | 42 ++++++++++++++++--- 4 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 backend/user/migrations/0004_bidder_saved_list.py diff --git a/backend/user/migrations/0004_bidder_saved_list.py b/backend/user/migrations/0004_bidder_saved_list.py new file mode 100644 index 0000000..2a454df --- /dev/null +++ b/backend/user/migrations/0004_bidder_saved_list.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.6 on 2024-01-23 01:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("vehicle", "0003_savedunits"), + ("user", "0003_remove_admin_password"), + ] + + operations = [ + migrations.AddField( + model_name="bidder", + name="saved_list", + field=models.ManyToManyField(to="vehicle.vehicle"), + ), + ] diff --git a/backend/user/models.py b/backend/user/models.py index d1240c3..76d39ac 100644 --- a/backend/user/models.py +++ b/backend/user/models.py @@ -3,6 +3,7 @@ from django.db import models from core.models import MainModel +from vehicle.models import Vehicle # Create your models here. @@ -24,6 +25,7 @@ class Bidder(MainModel): bidder_number = models.IntegerField(unique=True, blank=True, null=False) is_verified = models.BooleanField(default=False) is_blacklisted = models.BooleanField(default=False) + saved_list = models.ManyToManyField(Vehicle) def save(self, *args, **kwargs): # Check if the bidder_number is not set yet diff --git a/backend/vehicle/urls.py b/backend/vehicle/urls.py index f7a3659..fb1e281 100644 --- a/backend/vehicle/urls.py +++ b/backend/vehicle/urls.py @@ -1,10 +1,16 @@ from django.contrib import admin from django.urls import include, path -from .views import VehicleDetailApiView, VehicleFilterList, VehicleListApiView +from .views import ( + VehicleDetailApiView, + VehicleFilterList, + VehicleListApiView, + SaveUnitApiView, +) urlpatterns = [ path("", VehicleListApiView.as_view(), name="vehicle"), path("filter/", VehicleFilterList.as_view(), name="vehicle-list"), + path("save/", SaveUnitApiView.as_view(), name="save-unit-to-list"), path("/", VehicleDetailApiView.as_view(), name="vehicle_detail"), ] diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 0819be0..43cc78a 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -7,6 +7,7 @@ from .helpers import has_more_data, infinite_filter from .models import Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle +from user.models import Bidder from .serializers import ( BrandSerializer, EquipmentSerializer, @@ -41,8 +42,7 @@ def post(self, request, *args, **kwargs): brand = get_object_or_404(Brand, id=brand_id) if brand_id else None vehicle_type = get_object_or_404(Type, id=type_id) if type_id else None - vehicle = Vehicle.objects.create( - brand=brand, vehicle_type=vehicle_type, **data) + vehicle = Vehicle.objects.create(brand=brand, vehicle_type=vehicle_type, **data) # Use the serializer class's data directly serialized_data = self.serializer_class(vehicle) return Response(serialized_data.data, status=status.HTTP_201_CREATED) @@ -71,8 +71,7 @@ def put(self, request, vehicle_id, format=None): """ vehicle = get_object_or_404(Vehicle, id=vehicle_id) - serializer = VehicleSerializer( - vehicle, data=request.data) + serializer = VehicleSerializer(vehicle, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) @@ -105,8 +104,39 @@ def get(self, request): serialized_data = VehicleSerializer(vehicles, many=True) return Response( - {"vehicles": serialized_data.data, - "more_data": has_more_data(request)} + {"vehicles": serialized_data.data, "more_data": has_more_data(request)} ) return Response(VehicleSerializer(Vehicle.objects.all()[:10], many=True).data) + + +class SaveUnitApiView(APIView): + """ + An endpoint to handle saving a vehicle to a bidder's saved vehicle list + """ + + def get(self, request): + # Replace this line to obtain user id once authentication has been implemented + bidder_id = request.data.get("bidder_id") + try: + bidder = Bidder.objects.get(id=bidder_id) + vehicles = bidder.saved_list.all() + serialized_data = VehicleSerializer(vehicles, many=True) + return Response(serialized_data.data) + except Exception as e: + return Response("Bidder not found") + + def post(self, request): + vehicle_id = request.data.get("vehicle_id") + + # Replace this later to fetch authentication details from headers instead of body + bidder_id = request.data.get("bidder_id") + + try: + vehicle = Vehicle.objects.get(id=vehicle_id) + bidder = Bidder.objects.get(id=bidder_id) + + bidder.saved_list.add(vehicle) + return Response("Unit added successfully") + except Exception as e: + return Response("Bidder or vehicle not found") From 0613d2f998ccdb09d7011f850c62028c26285d88 Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:30:06 -0800 Subject: [PATCH 02/12] fixed styling --- backend/vehicle/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 43cc78a..d669da9 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -123,7 +123,7 @@ def get(self, request): vehicles = bidder.saved_list.all() serialized_data = VehicleSerializer(vehicles, many=True) return Response(serialized_data.data) - except Exception as e: + except Exception: return Response("Bidder not found") def post(self, request): @@ -138,5 +138,5 @@ def post(self, request): bidder.saved_list.add(vehicle) return Response("Unit added successfully") - except Exception as e: + except Exception: return Response("Bidder or vehicle not found") From 1ee617e13160958184c755ce91479ef3266a16cf Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:30:52 -0800 Subject: [PATCH 03/12] comments --- backend/vehicle/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index d669da9..6b90ae8 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -129,7 +129,8 @@ def get(self, request): def post(self, request): vehicle_id = request.data.get("vehicle_id") - # Replace this later to fetch authentication details from headers instead of body + # Replace this later to fetch authentication details + # from headers instead of body bidder_id = request.data.get("bidder_id") try: From 2391c53daf7cd46e848dbdc11bbe912202aefae4 Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:33:19 -0800 Subject: [PATCH 04/12] styling........please bro --- backend/vehicle/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 6b90ae8..1bb964b 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -129,7 +129,7 @@ def get(self, request): def post(self, request): vehicle_id = request.data.get("vehicle_id") - # Replace this later to fetch authentication details + # Replace this later to fetch authentication details # from headers instead of body bidder_id = request.data.get("bidder_id") From aeded1180de69217a351e4a6d4013d3034735f4a Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:41:04 -0800 Subject: [PATCH 05/12] add delete option --- backend/vehicle/views.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 1bb964b..6f12c59 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -132,12 +132,18 @@ def post(self, request): # Replace this later to fetch authentication details # from headers instead of body bidder_id = request.data.get("bidder_id") + delete = request.GET.get("delete") try: vehicle = Vehicle.objects.get(id=vehicle_id) bidder = Bidder.objects.get(id=bidder_id) - bidder.saved_list.add(vehicle) + if delete: + bidder.saved_list.remove(vehicle) + return Response("Unit removed from saved list") + else: + bidder.saved_list.add(vehicle) return Response("Unit added successfully") except Exception: return Response("Bidder or vehicle not found") + \ No newline at end of file From ad6e2d0d9b160a9728b4d5f15ea05d92f9d7168b Mon Sep 17 00:00:00 2001 From: KevinZhang Date: Mon, 22 Jan 2024 17:41:28 -0800 Subject: [PATCH 06/12] add delete endpoint --- backend/vehicle/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 6f12c59..933970c 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -146,4 +146,3 @@ def post(self, request): return Response("Unit added successfully") except Exception: return Response("Bidder or vehicle not found") - \ No newline at end of file From 6aa6d3d2f6f4a4cfa32254dcfe0893389ed8ba2b Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:06:47 -0800 Subject: [PATCH 07/12] add changes for demo only --- backend/auction/views.py | 2 +- .../user/migrations/0004_bidder_saved_list.py | 18 ----- backend/user/models.py | 3 +- backend/user/urls.py | 3 + backend/user/views.py | 65 ++++++++++++++++++- backend/vehicle/urls.py | 2 - backend/vehicle/views.py | 38 ----------- 7 files changed, 68 insertions(+), 63 deletions(-) delete mode 100644 backend/user/migrations/0004_bidder_saved_list.py diff --git a/backend/auction/views.py b/backend/auction/views.py index 1905f79..b9008e9 100644 --- a/backend/auction/views.py +++ b/backend/auction/views.py @@ -38,7 +38,7 @@ def post(self, request, *args, **kwargs): end_date = datetime.strptime(request.data.get("end_date"), date_format) # Check if start date is in the past - if start_date < datetime.now().date(): + if start_date.date() < datetime.now().date(): return Response( {"error": "Start date should be in the future"}, status=status.HTTP_400_BAD_REQUEST, diff --git a/backend/user/migrations/0004_bidder_saved_list.py b/backend/user/migrations/0004_bidder_saved_list.py deleted file mode 100644 index 2a454df..0000000 --- a/backend/user/migrations/0004_bidder_saved_list.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 4.2.6 on 2024-01-23 01:07 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("vehicle", "0003_savedunits"), - ("user", "0003_remove_admin_password"), - ] - - operations = [ - migrations.AddField( - model_name="bidder", - name="saved_list", - field=models.ManyToManyField(to="vehicle.vehicle"), - ), - ] diff --git a/backend/user/models.py b/backend/user/models.py index 76d39ac..ad3ddba 100644 --- a/backend/user/models.py +++ b/backend/user/models.py @@ -25,8 +25,7 @@ class Bidder(MainModel): bidder_number = models.IntegerField(unique=True, blank=True, null=False) is_verified = models.BooleanField(default=False) is_blacklisted = models.BooleanField(default=False) - saved_list = models.ManyToManyField(Vehicle) - + def save(self, *args, **kwargs): # Check if the bidder_number is not set yet if not self.bidder_number: diff --git a/backend/user/urls.py b/backend/user/urls.py index 1e8c1af..8c2c5ad 100644 --- a/backend/user/urls.py +++ b/backend/user/urls.py @@ -8,6 +8,7 @@ BidderDetailApiView, BidderListApiView, BidderVerifyApiView, + SaveUnitApiView ) urlpatterns = [ @@ -27,4 +28,6 @@ ), path("admins/", AdminListApiView.as_view(), name="admin-list"), path("admins//", AdminDetailApiView.as_view(), name="admin-detail"), + path("/vehicles/", SaveUnitApiView.as_view(), name="save-unit-to-list"), + ] diff --git a/backend/user/views.py b/backend/user/views.py index f87ce90..d6bdd8e 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -2,7 +2,7 @@ from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView - +from django.contrib.contenttypes.models import ContentType from .models import Admin, Bidder from .serializers import ( AdminSerializer, @@ -10,7 +10,9 @@ BidderSerializer, BidderVerifiedSerializer, ) - +from vehicle.models import Vehicle, SavedUnits, Type, Brand +from vehicle.serializers import VehicleSerializer +from auction.models import Auction, AuctionItem class BidderListApiView(APIView): def get(self, request): @@ -151,3 +153,62 @@ def delete(self, request, admin_id): admin = get_object_or_404(Admin, id=admin_id) admin.delete() return Response(status=status.HTTP_204_NO_CONTENT) + +class SaveUnitApiView(APIView): + """ + An endpoint to handle saving a vehicle to a bidder's saved vehicle list, as well as retrieving a list of all saved vehicles + """ + + def get(self, request, **kwargs): + # Replace this line to obtain user id once authentication has been implemented + bidder_id = kwargs.get("bidder_id") + bidder = get_object_or_404(Bidder, id=bidder_id) + + saved_units = SavedUnits.objects.filter(bidder_id=bidder) + vehicle_list = [saved_unit.content_object for saved_unit in saved_units if isinstance(saved_unit.content_object, Vehicle)] + + vehicle_data = [{"id": vehicle.id} for vehicle in vehicle_list] + + return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) + + + def post(self, request, **kwargs): + vehicle_id = kwargs.get("vehicle_id") + + # Replace this later to fetch authentication details + # from headers instead of body + bidder_id = kwargs.get("bidder_id") + bidder = Bidder.objects.create(email="sdfsdf@gmail.com", first_name="sdfsdf", last_name="sdfsdf", bidder_number="193334456") + #vehicle = get_object_or_404(Vehicle, id=vehicle_id) + brand = Brand.objects.create(name="sdfsdf") + type = Type.objects.create(name="sdfsdfsdf") + vehicle = Vehicle.objects.create(unicode_id=123348445, brand=brand, vehicle_type=type) + auction = Auction.objects.create(name="sdfsdf", start_date="2024-02-03", end_date="2024-02-23") + auction_item = AuctionItem(auction_id=auction, content_object=vehicle) + auction_item.save() + auction_for_vehicle = Auction.objects.filter(auctionitem__content_type=ContentType.objects.get_for_model(Vehicle), + auctionitem__object_id=vehicle.id).first() + #bidder = get_object_or_404(Bidder, id=bidder_id) + saved_unit = SavedUnits(auction_id=auction_for_vehicle, bidder_id=bidder, object_id=vehicle.id, content_object=vehicle) + saved_unit.save() + return Response(bidder.id) + return Response( + {"message": "Vehicle saved successfully"}, + status=status.HTTP_200_OK, + ) + + def delete(self, request, **kwargs): + vehicle_id = kwargs.get("vehicle_id") + bidder_id = kwargs.get("bidder_id") + + vehicle = get_object_or_404(Vehicle, id=vehicle_id) + bidder = get_object_or_404(Bidder, id=bidder_id) + + saved_unit = get_object_or_404(SavedUnits, vehicle_id=vehicle, bidder_id=bidder) + + saved_unit.delete() + + return Response( + {"message": "SavedUnit deleted successfully"}, + status=status.HTTP_200_OK, + ) diff --git a/backend/vehicle/urls.py b/backend/vehicle/urls.py index fb1e281..e380120 100644 --- a/backend/vehicle/urls.py +++ b/backend/vehicle/urls.py @@ -5,12 +5,10 @@ VehicleDetailApiView, VehicleFilterList, VehicleListApiView, - SaveUnitApiView, ) urlpatterns = [ path("", VehicleListApiView.as_view(), name="vehicle"), path("filter/", VehicleFilterList.as_view(), name="vehicle-list"), - path("save/", SaveUnitApiView.as_view(), name="save-unit-to-list"), path("/", VehicleDetailApiView.as_view(), name="vehicle_detail"), ] diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 933970c..37607d3 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -108,41 +108,3 @@ def get(self, request): ) return Response(VehicleSerializer(Vehicle.objects.all()[:10], many=True).data) - - -class SaveUnitApiView(APIView): - """ - An endpoint to handle saving a vehicle to a bidder's saved vehicle list - """ - - def get(self, request): - # Replace this line to obtain user id once authentication has been implemented - bidder_id = request.data.get("bidder_id") - try: - bidder = Bidder.objects.get(id=bidder_id) - vehicles = bidder.saved_list.all() - serialized_data = VehicleSerializer(vehicles, many=True) - return Response(serialized_data.data) - except Exception: - return Response("Bidder not found") - - def post(self, request): - vehicle_id = request.data.get("vehicle_id") - - # Replace this later to fetch authentication details - # from headers instead of body - bidder_id = request.data.get("bidder_id") - delete = request.GET.get("delete") - - try: - vehicle = Vehicle.objects.get(id=vehicle_id) - bidder = Bidder.objects.get(id=bidder_id) - - if delete: - bidder.saved_list.remove(vehicle) - return Response("Unit removed from saved list") - else: - bidder.saved_list.add(vehicle) - return Response("Unit added successfully") - except Exception: - return Response("Bidder or vehicle not found") From 4dadf0d858cc92a7b469f0375d087c3138c6faa2 Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Sat, 3 Feb 2024 00:08:52 -0800 Subject: [PATCH 08/12] add styling --- backend/user/models.py | 2 +- backend/user/urls.py | 9 ++++++--- backend/user/views.py | 45 +++++++++++++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/backend/user/models.py b/backend/user/models.py index ad3ddba..a0d93a2 100644 --- a/backend/user/models.py +++ b/backend/user/models.py @@ -25,7 +25,7 @@ class Bidder(MainModel): bidder_number = models.IntegerField(unique=True, blank=True, null=False) is_verified = models.BooleanField(default=False) is_blacklisted = models.BooleanField(default=False) - + def save(self, *args, **kwargs): # Check if the bidder_number is not set yet if not self.bidder_number: diff --git a/backend/user/urls.py b/backend/user/urls.py index 8c2c5ad..96b541d 100644 --- a/backend/user/urls.py +++ b/backend/user/urls.py @@ -8,7 +8,7 @@ BidderDetailApiView, BidderListApiView, BidderVerifyApiView, - SaveUnitApiView + SaveUnitApiView, ) urlpatterns = [ @@ -28,6 +28,9 @@ ), path("admins/", AdminListApiView.as_view(), name="admin-list"), path("admins//", AdminDetailApiView.as_view(), name="admin-detail"), - path("/vehicles/", SaveUnitApiView.as_view(), name="save-unit-to-list"), - + path( + "/vehicles/", + SaveUnitApiView.as_view(), + name="save-unit-to-list", + ), ] diff --git a/backend/user/views.py b/backend/user/views.py index d6bdd8e..c57e5c0 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -14,6 +14,7 @@ from vehicle.serializers import VehicleSerializer from auction.models import Auction, AuctionItem + class BidderListApiView(APIView): def get(self, request): """ @@ -153,7 +154,8 @@ def delete(self, request, admin_id): admin = get_object_or_404(Admin, id=admin_id) admin.delete() return Response(status=status.HTTP_204_NO_CONTENT) - + + class SaveUnitApiView(APIView): """ An endpoint to handle saving a vehicle to a bidder's saved vehicle list, as well as retrieving a list of all saved vehicles @@ -165,38 +167,57 @@ def get(self, request, **kwargs): bidder = get_object_or_404(Bidder, id=bidder_id) saved_units = SavedUnits.objects.filter(bidder_id=bidder) - vehicle_list = [saved_unit.content_object for saved_unit in saved_units if isinstance(saved_unit.content_object, Vehicle)] + vehicle_list = [ + saved_unit.content_object + for saved_unit in saved_units + if isinstance(saved_unit.content_object, Vehicle) + ] vehicle_data = [{"id": vehicle.id} for vehicle in vehicle_list] return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) - def post(self, request, **kwargs): vehicle_id = kwargs.get("vehicle_id") # Replace this later to fetch authentication details # from headers instead of body bidder_id = kwargs.get("bidder_id") - bidder = Bidder.objects.create(email="sdfsdf@gmail.com", first_name="sdfsdf", last_name="sdfsdf", bidder_number="193334456") - #vehicle = get_object_or_404(Vehicle, id=vehicle_id) + bidder = Bidder.objects.create( + email="sdfsdf@gmail.com", + first_name="sdfsdf", + last_name="sdfsdf", + bidder_number="193334456", + ) + # vehicle = get_object_or_404(Vehicle, id=vehicle_id) brand = Brand.objects.create(name="sdfsdf") type = Type.objects.create(name="sdfsdfsdf") - vehicle = Vehicle.objects.create(unicode_id=123348445, brand=brand, vehicle_type=type) - auction = Auction.objects.create(name="sdfsdf", start_date="2024-02-03", end_date="2024-02-23") + vehicle = Vehicle.objects.create( + unicode_id=123348445, brand=brand, vehicle_type=type + ) + auction = Auction.objects.create( + name="sdfsdf", start_date="2024-02-03", end_date="2024-02-23" + ) auction_item = AuctionItem(auction_id=auction, content_object=vehicle) auction_item.save() - auction_for_vehicle = Auction.objects.filter(auctionitem__content_type=ContentType.objects.get_for_model(Vehicle), - auctionitem__object_id=vehicle.id).first() - #bidder = get_object_or_404(Bidder, id=bidder_id) - saved_unit = SavedUnits(auction_id=auction_for_vehicle, bidder_id=bidder, object_id=vehicle.id, content_object=vehicle) + auction_for_vehicle = Auction.objects.filter( + auctionitem__content_type=ContentType.objects.get_for_model(Vehicle), + auctionitem__object_id=vehicle.id, + ).first() + # bidder = get_object_or_404(Bidder, id=bidder_id) + saved_unit = SavedUnits( + auction_id=auction_for_vehicle, + bidder_id=bidder, + object_id=vehicle.id, + content_object=vehicle, + ) saved_unit.save() return Response(bidder.id) return Response( {"message": "Vehicle saved successfully"}, status=status.HTTP_200_OK, ) - + def delete(self, request, **kwargs): vehicle_id = kwargs.get("vehicle_id") bidder_id = kwargs.get("bidder_id") From 3b452f1e50372181704358e134d078a1f6502b18 Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Sun, 4 Feb 2024 23:50:39 -0800 Subject: [PATCH 09/12] finished --- backend/user/views.py | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/backend/user/views.py b/backend/user/views.py index c57e5c0..e26d74d 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -178,33 +178,17 @@ def get(self, request, **kwargs): return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) def post(self, request, **kwargs): + bidder_id = kwargs.get("bidder_id") vehicle_id = kwargs.get("vehicle_id") - # Replace this later to fetch authentication details # from headers instead of body - bidder_id = kwargs.get("bidder_id") - bidder = Bidder.objects.create( - email="sdfsdf@gmail.com", - first_name="sdfsdf", - last_name="sdfsdf", - bidder_number="193334456", - ) - # vehicle = get_object_or_404(Vehicle, id=vehicle_id) - brand = Brand.objects.create(name="sdfsdf") - type = Type.objects.create(name="sdfsdfsdf") - vehicle = Vehicle.objects.create( - unicode_id=123348445, brand=brand, vehicle_type=type - ) - auction = Auction.objects.create( - name="sdfsdf", start_date="2024-02-03", end_date="2024-02-23" - ) - auction_item = AuctionItem(auction_id=auction, content_object=vehicle) - auction_item.save() + vehicle = get_object_or_404(Vehicle, id=vehicle_id) auction_for_vehicle = Auction.objects.filter( auctionitem__content_type=ContentType.objects.get_for_model(Vehicle), auctionitem__object_id=vehicle.id, ).first() - # bidder = get_object_or_404(Bidder, id=bidder_id) + + bidder = get_object_or_404(Bidder, id=bidder_id) saved_unit = SavedUnits( auction_id=auction_for_vehicle, bidder_id=bidder, @@ -212,7 +196,6 @@ def post(self, request, **kwargs): content_object=vehicle, ) saved_unit.save() - return Response(bidder.id) return Response( {"message": "Vehicle saved successfully"}, status=status.HTTP_200_OK, @@ -222,14 +205,15 @@ def delete(self, request, **kwargs): vehicle_id = kwargs.get("vehicle_id") bidder_id = kwargs.get("bidder_id") - vehicle = get_object_or_404(Vehicle, id=vehicle_id) bidder = get_object_or_404(Bidder, id=bidder_id) - saved_unit = get_object_or_404(SavedUnits, vehicle_id=vehicle, bidder_id=bidder) + saved_unit = get_object_or_404( + SavedUnits, object_id=vehicle_id, bidder_id=bidder + ) saved_unit.delete() return Response( - {"message": "SavedUnit deleted successfully"}, + {"message": "Saved unit deleted successfully"}, status=status.HTTP_200_OK, ) From 0ab6ee796b8303c8ca28390e69996431a70dfa36 Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Sun, 4 Feb 2024 23:56:39 -0800 Subject: [PATCH 10/12] styling --- backend/user/urls.py | 8 +++----- backend/user/views.py | 6 ++++-- backend/vehicle/admin.py | 10 +++++++++- backend/vehicle/helpers.py | 3 +-- backend/vehicle/serializers.py | 3 +-- backend/vehicle/urls.py | 3 +-- backend/vehicle/views.py | 13 +++++++++---- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/backend/user/urls.py b/backend/user/urls.py index 7bd5fe3..388031e 100644 --- a/backend/user/urls.py +++ b/backend/user/urls.py @@ -2,7 +2,6 @@ from django.urls import include, path from .views import ( -add-saved-list AdminDetailApiView, AdminListApiView, BidderBlacklistApiView, @@ -10,9 +9,9 @@ BidderListApiView, BidderVerifyApiView, SaveUnitApiView, - ListBlacklisted, - ListUnverified, - ListVerified + ListBlacklisted, + ListUnverified, + ListVerified, ) urlpatterns = [ @@ -40,5 +39,4 @@ path("bidders/unverified", ListUnverified.as_view(), name="unverified-list"), path("bidders/blacklisted", ListBlacklisted.as_view(), name="blacklisted-list"), path("bidders/verified", ListVerified.as_view(), name="verified-list"), - ] diff --git a/backend/user/views.py b/backend/user/views.py index a033dff..7d998da 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -15,7 +15,6 @@ from auction.models import Auction, AuctionItem - class BidderListApiView(APIView): def get(self, request): """ @@ -159,7 +158,8 @@ def delete(self, request, admin_id): class SaveUnitApiView(APIView): """ - An endpoint to handle saving a vehicle to a bidder's saved vehicle list, as well as retrieving a list of all saved vehicles + An endpoint to handle saving a vehicle to a bidder's saved vehicle list, + as well as retrieving a list of all saved vehicles """ def get(self, request, **kwargs): @@ -218,6 +218,8 @@ def delete(self, request, **kwargs): {"message": "Saved unit deleted successfully"}, status=status.HTTP_200_OK, ) + + class ListUnverified(APIView): def get(self, request): bidders = Bidder.objects.all() diff --git a/backend/vehicle/admin.py b/backend/vehicle/admin.py index d23ecd7..1d8d12b 100644 --- a/backend/vehicle/admin.py +++ b/backend/vehicle/admin.py @@ -2,7 +2,15 @@ from django.contrib.contenttypes.models import ContentType from .models import ( - Brand, Equipment, SavedUnits, Supplier, Trailer, Type, UnitImage, Vehicle) + Brand, + Equipment, + SavedUnits, + Supplier, + Trailer, + Type, + UnitImage, + Vehicle, +) class BrandAdmin(admin.ModelAdmin): diff --git a/backend/vehicle/helpers.py b/backend/vehicle/helpers.py index 64d0ba1..ec1037b 100644 --- a/backend/vehicle/helpers.py +++ b/backend/vehicle/helpers.py @@ -1,5 +1,4 @@ -from .models import ( - Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle) +from .models import Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle def infinite_filter(request): diff --git a/backend/vehicle/serializers.py b/backend/vehicle/serializers.py index 750ca4b..e80e7c3 100644 --- a/backend/vehicle/serializers.py +++ b/backend/vehicle/serializers.py @@ -1,7 +1,6 @@ from rest_framework import serializers -from .models import ( - Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle) +from .models import Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle class BrandSerializer(serializers.ModelSerializer): diff --git a/backend/vehicle/urls.py b/backend/vehicle/urls.py index ce53ea6..662428d 100644 --- a/backend/vehicle/urls.py +++ b/backend/vehicle/urls.py @@ -2,11 +2,10 @@ from django.urls import include, path from .views import ( - VehicleDetailApiView, VehicleFilterList, VehicleListApiView, - VehiclePriceApiView + VehiclePriceApiView, ) urlpatterns = [ diff --git a/backend/vehicle/views.py b/backend/vehicle/views.py index 1ba55d8..a1b8116 100644 --- a/backend/vehicle/views.py +++ b/backend/vehicle/views.py @@ -7,11 +7,16 @@ from .helpers import has_more_data, infinite_filter from user.models import Bidder -from .models import ( - Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle) +from .models import Brand, Equipment, Supplier, Trailer, Type, UnitImage, Vehicle from .serializers import ( - BrandSerializer, EquipmentSerializer, SupplierSerializer, - TrailerSerializer, TypeSerializer, UnitImageSerializer, VehicleSerializer) + BrandSerializer, + EquipmentSerializer, + SupplierSerializer, + TrailerSerializer, + TypeSerializer, + UnitImageSerializer, + VehicleSerializer, +) # Create your views here. From 67daea2aa40d4a0c7a01469fbe66416affce0338 Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Mon, 5 Feb 2024 20:57:07 -0800 Subject: [PATCH 11/12] moved API endpoints, added auction_id url params --- backend/auction/urls.py | 17 ++++++++- backend/auction/views.py | 81 ++++++++++++++++++++++++++++++++++++++++ backend/user/models.py | 1 - backend/user/urls.py | 6 --- backend/user/views.py | 64 ------------------------------- 5 files changed, 97 insertions(+), 72 deletions(-) diff --git a/backend/auction/urls.py b/backend/auction/urls.py index 91f7a2f..b000a1f 100644 --- a/backend/auction/urls.py +++ b/backend/auction/urls.py @@ -1,9 +1,24 @@ from django.contrib import admin from django.urls import include, path -from .views import AuctionDetailApiView, AuctionListApiView +from .views import ( + AuctionDetailApiView, + AuctionListApiView, + SaveUnitApiView, + GetSavedUnitApiView, +) urlpatterns = [ path("", AuctionListApiView.as_view(), name="auction_list"), path("/", AuctionDetailApiView.as_view(), name="auction_detail"), + path( + "/bidders//vehicles//", + SaveUnitApiView.as_view(), + name="auction_detail", + ), + path( + "/bidders//vehicles/", + GetSavedUnitApiView.as_view(), + name="auction_detail", + ), ] diff --git a/backend/auction/views.py b/backend/auction/views.py index b9008e9..eaa3144 100644 --- a/backend/auction/views.py +++ b/backend/auction/views.py @@ -7,6 +7,8 @@ from .models import Auction from .serializers import AuctionSerializer +from vehicle.models import Vehicle, SavedUnits, ContentType +from user.models import Bidder class AuctionListApiView(APIView): @@ -86,3 +88,82 @@ def delete(self, request, auction_id, format=None): auction = get_object_or_404(Auction, id=auction_id) auction.delete() return Response(status=status.HTTP_204_NO_CONTENT) + + +class SaveUnitApiView(APIView): + """ + An endpoint to handle saving a vehicle to a bidder's saved vehicle list, + as well as retrieving a list of all saved vehicles + """ + + def post(self, request, **kwargs): + bidder_id = kwargs.get("bidder_id") + vehicle_id = kwargs.get("vehicle_id") + auction_id = kwargs.get("auction_id") + + # Replace this later to fetch authentication details + # from headers instead of body + vehicle = get_object_or_404(Vehicle, id=vehicle_id) + auction_for_vehicle = Auction.objects.get(id=auction_id) + bidder = get_object_or_404(Bidder, id=bidder_id) + if SavedUnits.objects.filter( + auction_id=auction_for_vehicle, bidder_id=bidder, object_id=vehicle.id + ): + return Response( + {"message": "Vehicle already saved"}, + status=status.HTTP_204_NO_CONTENT, + ) + + saved_unit = SavedUnits( + auction_id=auction_for_vehicle, + bidder_id=bidder, + object_id=vehicle.id, + content_object=vehicle, + ) + saved_unit.save() + return Response( + {"message": "Vehicle saved successfully"}, + status=status.HTTP_200_OK, + ) + + def delete(self, request, **kwargs): + vehicle_id = kwargs.get("vehicle_id") + bidder_id = kwargs.get("bidder_id") + auction = kwargs.get("auction_id") + bidder = get_object_or_404(Bidder, id=bidder_id) + + saved_unit = get_object_or_404( + SavedUnits, object_id=vehicle_id, bidder_id=bidder, auction_id=auction + ) + + saved_unit.delete() + + return Response( + {"message": "Saved unit deleted successfully"}, + status=status.HTTP_200_OK, + ) + + +class GetSavedUnitApiView(APIView): + """ + An endpoint to retrieve all of bidder's saved units associated with + a provided auction + """ + + def get(self, request, **kwargs): + # Replace this line to obtain user id once authentication has been implemented + bidder_id = kwargs.get("bidder_id") + auction_id = kwargs.get("auction_id") + bidder = get_object_or_404(Bidder, id=bidder_id) + auction = get_object_or_404(Auction, id=auction_id) + + saved_units = SavedUnits.objects.filter(bidder_id=bidder, auction_id=auction) + vehicle_list = [ + saved_unit.content_object + for saved_unit in saved_units + if isinstance(saved_unit.content_object, Vehicle) + ] + + vehicle_data = [{"id": vehicle.id} for vehicle in vehicle_list] + + return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) diff --git a/backend/user/models.py b/backend/user/models.py index a0d93a2..d1240c3 100644 --- a/backend/user/models.py +++ b/backend/user/models.py @@ -3,7 +3,6 @@ from django.db import models from core.models import MainModel -from vehicle.models import Vehicle # Create your models here. diff --git a/backend/user/urls.py b/backend/user/urls.py index 388031e..6ff5cdf 100644 --- a/backend/user/urls.py +++ b/backend/user/urls.py @@ -8,7 +8,6 @@ BidderDetailApiView, BidderListApiView, BidderVerifyApiView, - SaveUnitApiView, ListBlacklisted, ListUnverified, ListVerified, @@ -31,11 +30,6 @@ ), path("admins/", AdminListApiView.as_view(), name="admin-list"), path("admins//", AdminDetailApiView.as_view(), name="admin-detail"), - path( - "/vehicles/", - SaveUnitApiView.as_view(), - name="save-unit-to-list", - ), path("bidders/unverified", ListUnverified.as_view(), name="unverified-list"), path("bidders/blacklisted", ListBlacklisted.as_view(), name="blacklisted-list"), path("bidders/verified", ListVerified.as_view(), name="verified-list"), diff --git a/backend/user/views.py b/backend/user/views.py index 7d998da..6f76341 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -156,70 +156,6 @@ def delete(self, request, admin_id): return Response(status=status.HTTP_204_NO_CONTENT) -class SaveUnitApiView(APIView): - """ - An endpoint to handle saving a vehicle to a bidder's saved vehicle list, - as well as retrieving a list of all saved vehicles - """ - - def get(self, request, **kwargs): - # Replace this line to obtain user id once authentication has been implemented - bidder_id = kwargs.get("bidder_id") - bidder = get_object_or_404(Bidder, id=bidder_id) - - saved_units = SavedUnits.objects.filter(bidder_id=bidder) - vehicle_list = [ - saved_unit.content_object - for saved_unit in saved_units - if isinstance(saved_unit.content_object, Vehicle) - ] - - vehicle_data = [{"id": vehicle.id} for vehicle in vehicle_list] - - return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) - - def post(self, request, **kwargs): - bidder_id = kwargs.get("bidder_id") - vehicle_id = kwargs.get("vehicle_id") - # Replace this later to fetch authentication details - # from headers instead of body - vehicle = get_object_or_404(Vehicle, id=vehicle_id) - auction_for_vehicle = Auction.objects.filter( - auctionitem__content_type=ContentType.objects.get_for_model(Vehicle), - auctionitem__object_id=vehicle.id, - ).first() - - bidder = get_object_or_404(Bidder, id=bidder_id) - saved_unit = SavedUnits( - auction_id=auction_for_vehicle, - bidder_id=bidder, - object_id=vehicle.id, - content_object=vehicle, - ) - saved_unit.save() - return Response( - {"message": "Vehicle saved successfully"}, - status=status.HTTP_200_OK, - ) - - def delete(self, request, **kwargs): - vehicle_id = kwargs.get("vehicle_id") - bidder_id = kwargs.get("bidder_id") - - bidder = get_object_or_404(Bidder, id=bidder_id) - - saved_unit = get_object_or_404( - SavedUnits, object_id=vehicle_id, bidder_id=bidder - ) - - saved_unit.delete() - - return Response( - {"message": "Saved unit deleted successfully"}, - status=status.HTTP_200_OK, - ) - - class ListUnverified(APIView): def get(self, request): bidders = Bidder.objects.all() From c29410db585b140fb0e27ac327add57a43f0d5e6 Mon Sep 17 00:00:00 2001 From: _Kevin_Zhang_ <49049813+Dragollax@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:01:27 -0800 Subject: [PATCH 12/12] resolve errors from merge conflict --- backend/auction/urls.py | 2 ++ backend/auction/views.py | 6 ++---- backend/user/views.py | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/backend/auction/urls.py b/backend/auction/urls.py index c26c66a..8c7cf2c 100644 --- a/backend/auction/urls.py +++ b/backend/auction/urls.py @@ -5,6 +5,7 @@ AuctionListApiView, SaveUnitApiView, GetSavedUnitApiView, + AddToAuctionApiView, ) @@ -20,6 +21,7 @@ "/bidders//vehicles/", GetSavedUnitApiView.as_view(), name="auction_detail", + ), path( "/vehicles/", AddToAuctionApiView.as_view(), diff --git a/backend/auction/views.py b/backend/auction/views.py index fed60d8..707825c 100644 --- a/backend/auction/views.py +++ b/backend/auction/views.py @@ -11,7 +11,6 @@ from user.models import Bidder - class AuctionListApiView(APIView): def get(self, request, *args, **kwargs): """ @@ -91,7 +90,6 @@ def delete(self, request, auction_id, format=None): return Response(status=status.HTTP_204_NO_CONTENT) - class SaveUnitApiView(APIView): """ An endpoint to handle saving a vehicle to a bidder's saved vehicle list, @@ -169,7 +167,8 @@ def get(self, request, **kwargs): vehicle_data = [{"id": vehicle.id} for vehicle in vehicle_list] return Response({"vehicles": vehicle_data}, status=status.HTTP_200_OK) - + + class AddToAuctionApiView(APIView): """ Takes in a vehicle and auction ID and associates @@ -190,4 +189,3 @@ def post(self, request, *args, **kwargs): {"message": "Vehicle added to auction successfully"}, status=status.HTTP_201_CREATED, ) - diff --git a/backend/user/views.py b/backend/user/views.py index 6f76341..6879314 100644 --- a/backend/user/views.py +++ b/backend/user/views.py @@ -10,9 +10,6 @@ BidderSerializer, BidderVerifiedSerializer, ) -from vehicle.models import Vehicle, SavedUnits, Type, Brand -from vehicle.serializers import VehicleSerializer -from auction.models import Auction, AuctionItem class BidderListApiView(APIView):