changed favorite routes structure

This commit is contained in:
Alexander Karpov 2023-05-27 23:57:56 +03:00
parent bc173cdbee
commit 268bf6ced3
3 changed files with 78 additions and 59 deletions

View File

@ -64,7 +64,10 @@ class RouteInputSerializer(serializers.Serializer):
city = serializers.CharField( city = serializers.CharField(
min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True
) )
movement = serializers.ChoiceField(['walk', 'bike', 'scooter', 'auto'], required=False, allow_blank=True) movement = serializers.ChoiceField(
["walk", "bike", "scooter", "auto"], required=False, allow_blank=True
)
stars = serializers.ListField( stars = serializers.ListField(
child=serializers.ChoiceField([1, 2, 3, 4, 5]), child=serializers.ChoiceField([1, 2, 3, 4, 5]),
required=False, required=False,
@ -72,18 +75,18 @@ class RouteInputSerializer(serializers.Serializer):
allow_null=True allow_null=True
) )
what_to_see = serializers.ListField( what_to_see = serializers.ListField(
child=serializers.ChoiceField( child=serializers.ChoiceField(
[ [
'attractions', 'attractions',
'museum', 'museum',
'movie', 'movie',
'concert', 'concert',
'artwork', 'artwork',
'plays', 'plays',
'shop', 'shop',
'gallery', 'gallery',
'theme_park', 'theme_park',
'viewpoint', 'viewpoint',
'zoo' 'zoo'
] ]
), ),
@ -123,42 +126,49 @@ class Meta:
fields = ["oid", "title", "description_short", "cities"] fields = ["oid", "title", "description_short", "cities"]
class InputPointJSONSerializer(serializers.Serializer):
oid = serializers.CharField(min_length=24, max_length=24)
class InputRoutePointSerializer(serializers.Serializer): class InputRoutePointSerializer(serializers.Serializer):
type = serializers.ChoiceField(choices=["point", "transition"]) type = serializers.ChoiceField(choices=["point", "transition"])
duration = serializers.IntegerField(min_value=0, required=True) time = serializers.IntegerField(min_value=0, required=True)
# point # point
point = serializers.CharField( point = InputPointJSONSerializer(required=False, allow_null=True)
min_length=24, max_length=24, required=False, allow_blank=True, allow_null=True
)
point_type = serializers.CharField( point_type = serializers.CharField(
required=False, allow_blank=True, allow_null=True required=False, allow_blank=True, allow_null=True
) )
# transition # transition
distance = serializers.FloatField(min_value=0, required=False, allow_null=True) distance = serializers.FloatField(required=False, allow_null=True)
def validate(self, data): def validate(self, data):
if data["type"] == "point": if data["type"] == "point":
if "point" not in data or not data["point"]: if (
"point" not in data
or not data["point"]
or "oid" not in data["point"]
or not data["point"]["oid"]
):
raise serializers.ValidationError("Point id is required") raise serializers.ValidationError("Point id is required")
get_object_or_404(BasePoint, oid=data["point"]) get_object_or_404(BasePoint, oid=data["point"]["oid"])
if "distance" not in data or not data["point_type"]: if "point_type" not in data or not data["point_type"]:
raise serializers.ValidationError("Point type is required") raise serializers.ValidationError("Point type is required")
else: else:
if "distance" not in data or not data["distance"]: if "distance" not in data:
raise serializers.ValidationError("Distance is required") raise serializers.ValidationError("Distance is required")
return data return data
class InputRouteDateSerializer(serializers.Serializer): class InputRouteDateSerializer(serializers.Serializer):
date = serializers.DateField() date = serializers.DateTimeField()
points = serializers.ListSerializer(child=InputRoutePointSerializer()) paths = serializers.ListSerializer(child=InputRoutePointSerializer())
class InputRouteSerializer(serializers.Serializer): class InputRouteSerializer(serializers.Serializer):
dates = serializers.ListSerializer(child=InputRouteDateSerializer()) points = serializers.ListSerializer(child=InputRouteDateSerializer())
class ListUserRouteSerializer(serializers.ModelSerializer): class ListUserRouteSerializer(serializers.ModelSerializer):
@ -168,7 +178,7 @@ class Meta:
class UserRouteDateSerializer(serializers.ModelSerializer): class UserRouteDateSerializer(serializers.ModelSerializer):
points = serializers.SerializerMethodField(method_name="get_points") paths = serializers.SerializerMethodField(method_name="get_points")
@extend_schema_field(InputRoutePointSerializer) @extend_schema_field(InputRoutePointSerializer)
def get_points(self, obj): def get_points(self, obj):
@ -176,13 +186,15 @@ def get_points(self, obj):
class Meta: class Meta:
model = UserRouteDate model = UserRouteDate
fields = ["date", "points"] fields = ["date", "paths"]
class UserRouteSerializer(serializers.ModelSerializer): class UserRouteSerializer(serializers.ModelSerializer):
points = UserRouteDateSerializer(many=True, source="dates")
class Meta: class Meta:
model = UserRoute model = UserRoute
fields = ["created", "dates"] fields = ["created", "points"]
class RestaurantSerializer(serializers.ModelSerializer): class RestaurantSerializer(serializers.ModelSerializer):

View File

@ -1,3 +1,4 @@
from django.utils.dateparse import parse_datetime
from rest_framework.generics import ( from rest_framework.generics import (
GenericAPIView, GenericAPIView,
ListAPIView, ListAPIView,
@ -70,51 +71,50 @@ def post(self, request):
city_id = data["city"] city_id = data["city"]
start_date = datetime.strptime(data['date_from'], '%Y-%m-%d') start_date = datetime.strptime(data['date_from'], '%Y-%m-%d')
end_date = datetime.strptime(data['date_to'], '%Y-%m-%d') end_date = datetime.strptime(data['date_to'], '%Y-%m-%d')
try: try:
movement = data['movement'] movement = data['movement']
except KeyError: except KeyError:
movement = 'walk' movement = 'walk'
hotel_stars = data['stars'] hotel_stars = data['stars']
if hotel_stars is None: if hotel_stars is None:
hotel_stars = [] hotel_stars = []
hotel_type = data['where_stay'] hotel_type = data['where_stay']
if hotel_type is None: if hotel_type is None:
hotel_type = ['hotel'] hotel_type = ['hotel']
where_eat = data['where_eat'] where_eat = data['where_eat']
if where_eat is None: if where_eat is None:
where_eat = ['restaurant', 'bar', 'cafe'] where_eat = ['restaurant', 'bar', 'cafe']
what_to_see = data['what_to_see'] what_to_see = data['what_to_see']
if what_to_see is None: if what_to_see is None:
what_to_see = [ what_to_see = [
'attractions', 'attractions',
'museum', 'museum',
'movie', 'movie',
'concert', 'concert',
'artwork', 'artwork',
'plays', 'plays',
'shop', 'shop',
'gallery', 'gallery',
'theme_park', 'theme_park',
'viewpoint', 'viewpoint',
'zoo' 'zoo'
] ]
if 'hotel' not in hotel_type: if 'hotel' not in hotel_type:
hotel_stars = [] hotel_stars = []
region = None region = None
if city_id: if city_id:
region = get_object_or_404(City, oid=city_id) region = get_object_or_404(City, oid=city_id)
else: else:
region = choice(City.objects.annotate(points_count=Count('points')).filter(title__in=city_in_hotels).filter(points_count__gt=400)) region = choice(City.objects.annotate(points_count=Count('points')).filter(title__in=city_in_hotels).filter(
points_count__gt=400))
if not start_date and end_date: if not start_date and end_date:
tour_length = choice([timedelta(days=i) for i in range(1, 4)]) tour_length = choice([timedelta(days=i) for i in range(1, 4)])
start_date = end_date - tour_length start_date = end_date - tour_length
@ -130,10 +130,10 @@ def post(self, request):
print(request.user, region, start_date, end_date) print(request.user, region, start_date, end_date)
tour = generate_tour( tour = generate_tour(
request.user, request.user,
region, region,
start_date, start_date,
end_date, end_date,
avg_velocity=movement_mapping[movement], avg_velocity=movement_mapping[movement],
stars=hotel_stars, stars=hotel_stars,
hotel_type=hotel_type, hotel_type=hotel_type,
@ -165,19 +165,21 @@ def post(self, request, *args, **kwargs):
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
data = serializer.data data = serializer.data
route = UserRoute.objects.create(user=self.request.user) route = UserRoute.objects.create(user=self.request.user)
for date in data["dates"]: for date in data["points"]:
date_obj = UserRouteDate.objects.create(date=date["date"], route=route) date_obj = UserRouteDate.objects.create(
for point in date["points"]: date=parse_datetime(date["date"]).date(), route=route
)
for point in date["paths"]:
if point["type"] == "point": if point["type"] == "point":
UserRoutePoint.objects.create( UserRoutePoint.objects.create(
date=date_obj, date=date_obj,
duration=point["duration"], duration=point["time"],
point=BasePoint.objects.get(oid=point["point"]), point=BasePoint.objects.get(oid=point["point"]["oid"]),
) )
else: else:
UserRouteTransaction.objects.create( UserRouteTransaction.objects.create(
date=date_obj, date=date_obj,
duration=point["duration"], duration=point["time"],
distance=point["distance"], distance=point["distance"],
) )

View File

@ -272,10 +272,15 @@ class UserRoutePoint(BaseUserRouteDatePoint):
def get_json(self): def get_json(self):
return { return {
"type": "point", "type": "point",
"duration": self.duration, "point": {
"point": self.point.oid, "lat": self.point.lat,
"point_name": self.point.title, "lon": self.point.lon,
"title": self.point.title,
"description": self.point.description,
"oid": self.point.oid
},
"point_type": self.point_type, "point_type": self.point_type,
"time": self.duration,
} }
@ -286,6 +291,6 @@ class UserRouteTransaction(BaseUserRouteDatePoint):
def get_json(self): def get_json(self):
return { return {
"type": "transition", "type": "transition",
"duration": self.duration,
"distance": self.distance, "distance": self.distance,
"time": self.duration,
} }