-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from ubcuas/gcom-51/routes-implementation
Waypoint Routes Endpoints
- Loading branch information
Showing
8 changed files
with
274 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
from django.contrib import admin | ||
|
||
from nav.models import Route, Waypoint | ||
|
||
# from django.contrib import admin | ||
|
||
# Register your models here. | ||
admin.site.register(Waypoint) | ||
admin.site.register(Route) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Generated by Django 5.0.6 on 2024-10-06 02:03 | ||
|
||
import django.db.models.deletion | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("nav", "0001_initial"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="Route", | ||
fields=[ | ||
( | ||
"id", | ||
models.BigAutoField( | ||
auto_created=True, | ||
primary_key=True, | ||
serialize=False, | ||
verbose_name="ID", | ||
), | ||
), | ||
("name", models.CharField(max_length=32)), | ||
], | ||
), | ||
migrations.AddField( | ||
model_name="waypoint", | ||
name="route", | ||
field=models.ForeignKey( | ||
default=1, | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="waypoints", | ||
to="nav.route", | ||
), | ||
preserve_default=False, | ||
), | ||
] |
29 changes: 29 additions & 0 deletions
29
src/nav/migrations/0003_remove_waypoint_route_orderedwaypoint_route.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Generated by Django 5.0.6 on 2024-10-06 03:03 | ||
|
||
import django.db.models.deletion | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("nav", "0002_route_waypoint_route"), | ||
] | ||
|
||
operations = [ | ||
migrations.RemoveField( | ||
model_name="waypoint", | ||
name="route", | ||
), | ||
migrations.AddField( | ||
model_name="orderedwaypoint", | ||
name="route", | ||
field=models.ForeignKey( | ||
default=1, | ||
on_delete=django.db.models.deletion.CASCADE, | ||
related_name="waypoints", | ||
to="nav.route", | ||
), | ||
preserve_default=False, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,21 @@ | ||
from rest_framework import serializers | ||
from .models import Waypoint | ||
from .models import OrderedWaypoint, Route | ||
|
||
|
||
class WaypointSerializer(serializers.ModelSerializer): | ||
class OrderedWaypointSerializer(serializers.ModelSerializer): | ||
"""Serializer to convert Waypoint objects to JSON""" | ||
|
||
class Meta: | ||
model = Waypoint | ||
model = OrderedWaypoint | ||
ordering = ["order"] | ||
fields = "__all__" | ||
|
||
|
||
class RouteSerializer(serializers.ModelSerializer): | ||
"""Serializer to convert Route objects to JSON""" | ||
|
||
waypoints = OrderedWaypointSerializer(many=True, read_only=True) | ||
|
||
class Meta: | ||
model = Route | ||
fields = ["id", "name", "waypoints"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,65 @@ | ||
from rest_framework import viewsets | ||
from .models import Waypoint | ||
from .serializers import WaypointSerializer | ||
from .models import Route, OrderedWaypoint | ||
from .serializers import RouteSerializer, OrderedWaypointSerializer | ||
from rest_framework.decorators import action | ||
from rest_framework.response import Response | ||
from rest_framework import status | ||
|
||
|
||
# Create your views here. | ||
class WaypointViewset(viewsets.ModelViewSet): | ||
class OrderedWaypointViewset(viewsets.ModelViewSet): | ||
"""Viewset for CRUD operations on Waypoints""" | ||
|
||
queryset = Waypoint.objects.all() | ||
serializer_class = WaypointSerializer | ||
queryset = OrderedWaypoint.objects.all() | ||
serializer_class = OrderedWaypointSerializer | ||
|
||
def get_serializer(self, *args, **kwargs): | ||
if isinstance(kwargs.get("data", {}), list): | ||
kwargs["many"] = True | ||
|
||
return super(WaypointViewset, self).get_serializer(*args, **kwargs) | ||
return super(OrderedWaypointViewset, self).get_serializer(*args, **kwargs) | ||
|
||
|
||
class RoutesViewset(viewsets.ModelViewSet): | ||
"""Viewset for CRUD operations on Routes""" | ||
|
||
queryset = Route.objects.all().prefetch_related("waypoints") | ||
serializer_class = RouteSerializer | ||
|
||
@action(detail=True, methods=["post"], url_path="reorder-waypoints") | ||
def reorder_waypoints(self, request, pk=None): | ||
""" | ||
Action to reorder waypoints in a route | ||
Args: | ||
request: The request object - contains the reordered waypoint ids | ||
pk: The primary key of the route whose waypoints we're reordering | ||
""" | ||
route = self.get_object() | ||
|
||
waypoints = OrderedWaypoint.objects.filter(route=route) | ||
|
||
if ( | ||
not request.data | ||
or not isinstance(request.data, list) | ||
or len(request.data) != len(waypoints) | ||
): | ||
return Response( | ||
{"error": "Please provide a list of all waypoint IDs"}, | ||
status=status.HTTP_400_BAD_REQUEST, | ||
) | ||
|
||
reordered_waypoint_ids = request.data | ||
for idx, waypoint_id in enumerate(reordered_waypoint_ids): | ||
try: | ||
waypoint = waypoints.get(id=waypoint_id) | ||
waypoint.order = idx | ||
waypoint.save() | ||
except OrderedWaypoint.DoesNotExist: | ||
return Response( | ||
{"error": f"Waypoint with not found with id: {waypoint_id}"}, | ||
status=status.HTTP_400_BAD_REQUEST, | ||
) | ||
|
||
return Response( | ||
{"success": "Waypoints reordered successfully"}, status=status.HTTP_200_OK | ||
) |