from django.db import models from core.enums import SchoolLevel, SchoolNature, SchoolType from core.models.base import TimeStampedModel class District(TimeStampedModel): city = models.CharField( max_length=50, verbose_name="所属城市", help_text="支持多城市扩展,如「上海」「北京」", ) name = models.CharField( max_length=50, verbose_name="行政区名称", help_text="如「静安区」", ) short_name = models.CharField( max_length=20, blank=True, default="", verbose_name="简称", help_text="如「静安」", ) sort_order = models.IntegerField( default=0, verbose_name="排序", help_text="列表展示排序", ) is_active = models.BooleanField( default=True, verbose_name="是否启用", help_text="False=已停用,不在筛选项中展示", ) class Meta: db_table = "districts" verbose_name = "城区" verbose_name_plural = "城区" constraints = [ models.UniqueConstraint( fields=["city", "name"], condition=models.Q(is_active=True), name="uq_districts_city_name", ), ] ordering = ["city", "sort_order", "name"] def __str__(self) -> str: return f"{self.city} / {self.name}" class BusinessArea(TimeStampedModel): district = models.ForeignKey( "region.District", on_delete=models.PROTECT, related_name="business_areas", verbose_name="所属城区", ) name = models.CharField( max_length=100, verbose_name="商圈名称", ) sort_order = models.IntegerField( default=0, verbose_name="排序", ) latitude = models.DecimalField( max_digits=10, decimal_places=7, null=True, blank=True, verbose_name="商圈中心纬度", ) longitude = models.DecimalField( max_digits=10, decimal_places=7, null=True, blank=True, verbose_name="商圈中心经度", ) is_active = models.BooleanField( default=True, verbose_name="是否启用", help_text="False=已停用,不在筛选项中展示", ) class Meta: db_table = "business_areas" verbose_name = "商圈" verbose_name_plural = "商圈" constraints = [ models.UniqueConstraint( fields=["district", "name"], name="uq_business_areas_name", ), ] indexes = [ models.Index( fields=["district"], name="idx_business_areas_district", condition=models.Q(is_active=True), ), ] ordering = ["district_id", "sort_order", "name"] def __str__(self) -> str: return self.name class MetroLine(TimeStampedModel): city = models.CharField( max_length=50, verbose_name="所属城市", ) name = models.CharField( max_length=50, verbose_name="线路名称", help_text="如「1号线」", ) color = models.CharField( max_length=7, blank=True, default="", verbose_name="线路颜色", help_text="HEX 色值,如 #E3002B", ) sort_order = models.IntegerField( default=0, verbose_name="排序", ) is_active = models.BooleanField( default=True, verbose_name="是否启用", help_text="False=已停用,不在筛选项中展示", ) class Meta: db_table = "metro_lines" verbose_name = "地铁线路" verbose_name_plural = "地铁线路" ordering = ["city", "sort_order", "name"] def __str__(self) -> str: return f"{self.city} {self.name}" class MetroStation(TimeStampedModel): metro_line = models.ForeignKey( "region.MetroLine", on_delete=models.CASCADE, related_name="stations", verbose_name="所属线路", ) name = models.CharField( max_length=50, verbose_name="站名", ) latitude = models.DecimalField( max_digits=10, decimal_places=7, null=True, blank=True, verbose_name="站点纬度", ) longitude = models.DecimalField( max_digits=10, decimal_places=7, null=True, blank=True, verbose_name="站点经度", ) sort_order = models.IntegerField( default=0, verbose_name="沿线排序", ) is_active = models.BooleanField( default=True, verbose_name="是否启用", help_text="False=已停用,不在筛选项中展示", ) class Meta: db_table = "metro_stations" verbose_name = "地铁站点" verbose_name_plural = "地铁站点" indexes = [ models.Index( fields=["metro_line"], name="idx_metro_stations_line", condition=models.Q(is_active=True), ), ] ordering = ["metro_line_id", "sort_order"] def __str__(self) -> str: return self.name class School(TimeStampedModel): district = models.ForeignKey( "region.District", null=True, blank=True, on_delete=models.SET_NULL, related_name="schools", verbose_name="所属城区", ) name = models.CharField( max_length=100, verbose_name="学校名称", ) type = models.CharField( max_length=20, blank=True, default="", choices=SchoolType.choices, verbose_name="学校类型", help_text="primary=小学 / middle=初中 / high=高中 / k9=九年一贯制 / k12=十二年一贯制", ) nature = models.CharField( max_length=20, blank=True, default="", choices=SchoolNature.choices, verbose_name="学校性质", help_text="public=公立 / private=私立 / international=国际学校", ) level = models.CharField( max_length=20, blank=True, default="", choices=SchoolLevel.choices, verbose_name="学校等级", help_text="normal=普通 / key=重点 / top=名校", ) is_active = models.BooleanField( default=True, verbose_name="是否启用", help_text="False=已停用,不在筛选项中展示", ) class Meta: db_table = "schools" verbose_name = "学校" verbose_name_plural = "学校" indexes = [ models.Index( fields=["district"], name="idx_schools_district", condition=models.Q(is_active=True), ), ] ordering = ["name"] def __str__(self) -> str: return self.name