backend/passfinder/events/models.py

268 lines
8.7 KiB
Python
Raw Normal View History

2023-05-19 20:14:44 +03:00
from django.contrib.postgres.fields import ArrayField
2023-05-18 22:43:35 +03:00
from django.db import models
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema_field
from rest_framework.serializers import ListSerializer, FloatField
2023-05-18 22:43:35 +03:00
from polymorphic.models import PolymorphicModel
2023-05-20 16:47:08 +03:00
from passfinder.utils.choices import count_max_length
2023-05-18 22:43:35 +03:00
class OIDModel(models.Model):
2023-05-20 16:47:08 +03:00
oid = models.CharField(primary_key=True, max_length=24, unique=True)
2023-05-18 22:43:35 +03:00
class Meta:
abstract = True
class Region(OIDModel):
2023-05-20 16:47:08 +03:00
city = models.ForeignKey(
"City", null=True, related_name="regions", on_delete=models.CASCADE
)
2023-05-18 22:43:35 +03:00
title = models.CharField(max_length=250)
2023-05-20 16:47:08 +03:00
description = models.TextField()
description_title = models.CharField(max_length=250)
description_short = models.CharField(max_length=500)
url = models.URLField()
showcase_cards = models.JSONField(null=True)
2023-05-18 22:43:35 +03:00
2023-05-19 20:14:44 +03:00
def __str__(self):
return self.title
2023-05-18 22:43:35 +03:00
2023-05-20 16:47:08 +03:00
class RegionMedia(OIDModel):
file = models.FileField(upload_to="uploads/")
type = models.CharField(max_length=200)
region = models.ForeignKey("Region", related_name="media", on_delete=models.CASCADE)
2023-05-19 20:14:44 +03:00
2023-05-18 22:43:35 +03:00
class City(OIDModel):
title = models.CharField(max_length=250)
region = models.ForeignKey(
"Region", related_name="cities", null=True, on_delete=models.SET_NULL
)
2023-05-21 20:46:07 +03:00
lon = models.FloatField(default=0, db_index=True)
lat = models.FloatField(default=0, db_index=True)
@property
def location(self):
return [self.lat, self.lon]
2023-05-18 22:43:35 +03:00
2023-05-19 20:14:44 +03:00
def __str__(self):
return self.title
class Place(OIDModel):
2023-05-20 16:47:08 +03:00
address = models.CharField(max_length=250, null=True, blank=True)
2023-05-19 20:14:44 +03:00
parser_source = models.CharField(max_length=250)
city = models.ForeignKey(
"City", related_name="places", null=True, on_delete=models.SET_NULL
)
2023-05-20 16:47:08 +03:00
region = models.ForeignKey(
"Region", related_name="places", null=True, on_delete=models.SET_NULL
)
title = models.CharField(max_length=250)
2023-05-19 20:14:44 +03:00
description = models.TextField()
2023-05-21 20:46:07 +03:00
lon = models.FloatField(default=0, db_index=True)
lat = models.FloatField(default=0, db_index=True)
2023-05-20 16:47:08 +03:00
sites = ArrayField(models.CharField(max_length=250), null=True)
phones = ArrayField(models.CharField(max_length=250), null=True)
2023-05-19 20:14:44 +03:00
working_time = models.JSONField(null=True)
2023-05-21 20:46:07 +03:00
@property
def location(self):
return [self.lat, self.lon]
2023-05-21 20:46:07 +03:00
2023-05-18 22:43:35 +03:00
2023-05-24 13:32:17 +03:00
class Category(OIDModel):
name = models.CharField(max_length=500, unique=True)
description = models.TextField()
2023-05-18 22:43:35 +03:00
2023-05-19 20:14:44 +03:00
def __str__(self):
return self.name
2023-05-18 22:43:35 +03:00
2023-05-24 13:32:17 +03:00
class PointCategory(models.Model):
point = models.ForeignKey(
"BasePoint", related_name="categories", on_delete=models.CASCADE
)
category = models.ForeignKey(
"Category", related_name="points", on_delete=models.CASCADE
)
class Meta:
unique_together = ("point", "category")
2023-05-19 20:14:44 +03:00
class BasePoint(OIDModel, PolymorphicModel):
2023-05-23 18:14:06 +03:00
title = models.CharField(max_length=500)
2023-05-20 16:47:08 +03:00
parser_source = models.CharField(max_length=250, null=True, blank=True)
2023-05-18 22:43:35 +03:00
description = models.TextField()
city = models.ForeignKey(
2023-05-19 20:14:44 +03:00
"City", related_name="points", null=True, on_delete=models.SET_NULL
2023-05-18 22:43:35 +03:00
)
region = models.ForeignKey(
"Region", related_name="points", null=True, on_delete=models.SET_NULL
)
2023-05-20 16:47:08 +03:00
place = models.ForeignKey(
"Place", related_name="points", null=True, on_delete=models.SET_NULL
)
sort = models.IntegerField(default=0)
2023-05-21 20:46:07 +03:00
lat = models.FloatField(default=0, db_index=True)
lon = models.FloatField(default=0, db_index=True)
2023-05-20 16:47:08 +03:00
can_buy = models.BooleanField(default=True)
priority = models.BooleanField(default=False)
2023-05-26 20:49:24 +03:00
price = models.IntegerField(null=True)
2023-05-19 20:14:44 +03:00
2023-05-21 20:46:07 +03:00
@property
@extend_schema_field(
field=ListSerializer(child=FloatField(), min_length=2, max_length=2)
)
2023-05-21 20:46:07 +03:00
def location(self):
return [self.lat, self.lon]
2023-05-21 20:46:07 +03:00
2023-05-26 01:15:02 +03:00
@property
@extend_schema_field(
field=ListSerializer(child=FloatField(), min_length=2, max_length=2)
)
def location_dec(self):
return [float(format(self.lat, ".6f")), float(format(self.lon, ".6f"))]
2023-05-21 20:46:07 +03:00
@property
@extend_schema_field(field=OpenApiTypes.URI)
2023-05-21 20:46:07 +03:00
def icon(self):
2023-05-26 01:15:02 +03:00
if self.media:
return self.media.last().file.url
return ""
2023-05-21 20:46:07 +03:00
2023-05-19 20:14:44 +03:00
def __str__(self):
return self.title
class PointMedia(OIDModel):
file = models.FileField(upload_to="uploads/")
type = models.CharField(max_length=200)
point = models.ForeignKey(
"BasePoint", related_name="media", on_delete=models.CASCADE
)
class Event(BasePoint):
2023-05-20 16:47:08 +03:00
class EventType(models.TextChoices):
yarmarka = "fair", "ярмарка"
bulvar = "boulevard", "бульвар"
dostoprimechatelnost = "attraction", "достопримечательность"
excursii = "excursion", "экскурсия"
teatr = "theatre", "театр"
museum = "museum", "музей"
kino = "movie", "кино"
concert = "concert", "концерт"
spektatli = "plays", "спектакли"
2023-05-26 11:55:02 +03:00
artwork = "artwork", "произведение искусства"
shop = "shop", "торговый центр"
gallery = "gallery", "галерея"
theme_park = "theme_park", "тематический парк"
viewpoint = "viewpoint", "обзорная точка"
zoo = "zoo", "зоопарк"
other = "other", "другое"
2023-05-20 16:47:08 +03:00
2023-05-23 18:14:06 +03:00
address = models.CharField(max_length=250, null=True)
2023-05-20 16:47:08 +03:00
payment_method = models.CharField(max_length=250, null=True, blank=True)
type = models.CharField(
db_index=True,
choices=EventType.choices,
max_length=count_max_length(EventType),
)
age = models.CharField(
"Возрастное ограничение", max_length=50, blank=True, null=True
)
booking_link = models.URLField(null=True, blank=True)
discover_moscow_link = models.URLField(null=True, blank=True)
2023-05-19 20:14:44 +03:00
duration = models.IntegerField(blank=True, null=True)
ticket_price = models.IntegerField(blank=True, null=True)
schedule = models.JSONField(null=True)
2023-05-23 18:14:06 +03:00
extra_kwargs = models.JSONField(null=True)
2023-05-19 20:14:44 +03:00
class Hotel(BasePoint):
2023-05-26 01:15:02 +03:00
class HotelType(models.TextChoices):
hotel = "hotel", "отель"
hostel = "hostel", "хостел"
guest_house = "guest_house", "гостевой дом"
motel = "motel", "мотель"
2023-05-26 01:45:14 +03:00
apartment = "apartment", "квартира"
chalet = "chalet", "домик"
2023-05-26 01:15:02 +03:00
type = models.CharField(
db_index=True,
default=HotelType.hotel,
choices=HotelType.choices,
max_length=count_max_length(HotelType),
)
address = models.CharField(max_length=500, null=True, blank=True)
2023-05-19 20:14:44 +03:00
rooms = models.JSONField(null=True)
2023-05-26 01:15:02 +03:00
email = models.CharField(max_length=250, null=True, blank=True)
2023-05-19 20:14:44 +03:00
stars = models.IntegerField(null=True)
2023-05-26 01:15:02 +03:00
extra_kwargs = models.JSONField(null=True)
2023-05-19 20:14:44 +03:00
class HotelPhone(models.Model):
hotel = models.ForeignKey("Hotel", related_name="phones", on_delete=models.CASCADE)
name = models.CharField(max_length=50)
number = models.CharField(max_length=18)
class Restaurant(BasePoint):
2023-05-26 11:55:02 +03:00
class RestaurantType(models.TextChoices):
restaurant = "restaurant", "ресторан"
bar = "bar", "бар"
cafe = "cafe", "кафе"
type = models.CharField(
db_index=True,
default=RestaurantType.restaurant,
choices=RestaurantType.choices,
max_length=count_max_length(RestaurantType),
)
address = models.CharField(max_length=250, blank=True, null=True)
2023-05-21 10:08:30 +03:00
bill = models.IntegerField(null=True)
can_reserve = models.BooleanField(default=True)
avg_time_visit = models.IntegerField(null=True)
2023-05-19 20:14:44 +03:00
working_time = models.JSONField(null=True)
2023-05-21 10:08:30 +03:00
phones = ArrayField(models.CharField(max_length=18), null=True)
2023-05-26 16:26:01 +03:00
extra_kwargs = models.JSONField(null=True)
class UserRoute(models.Model):
user = models.ForeignKey(
"users.User", related_name="routes", on_delete=models.CASCADE
)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.user}'s route"
class BaseUserRoutePoint(PolymorphicModel):
route = models.ForeignKey(
"UserRoute", related_name="points", on_delete=models.CASCADE
)
class UserRoutePoint(BaseUserRoutePoint):
type = "point"
point = models.ForeignKey("BasePoint", on_delete=models.CASCADE)
class UserRouteTransaction(BaseUserRoutePoint):
type = "transition"
point_from = models.ForeignKey(
"BasePoint", related_name="user_route_point_from", on_delete=models.CASCADE
)
point_to = models.ForeignKey(
"BasePoint", related_name="user_route_point_to", on_delete=models.CASCADE
)
distance = models.FloatField()