feat(property): add Chinese verbose_name and help_text to all property fields (Phase 4.1)

Sync DATA_MODEL_PROPERTY.md field-level Chinese annotations to Django
models across 23 property tables. Adds verbose_name= and help_text= to
every field in core.py, follow_keys.py, listings.py, media.py.

Pre-existing partitioned-table docstrings on FollowLog/PropertyPhoto
retained (signal Django ORM treats parent as unmanaged, RunSQL managed).
This commit is contained in:
2026-04-30 09:15:43 +08:00
parent 79c3cf2924
commit 3638fc0302
4 changed files with 1328 additions and 243 deletions

View File

@@ -11,24 +11,65 @@ from core.models.base import UUIDPrimaryKeyModel
class FieldSurvey(UUIDPrimaryKeyModel):
property = models.ForeignKey(
"fonrey_property.Property", on_delete=models.CASCADE, related_name="field_surveys"
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="field_surveys",
verbose_name="所属房源",
)
status = models.CharField(
max_length=10,
choices=PropertyFieldSurveyStatus.choices,
default=PropertyFieldSurveyStatus.DRAFT,
verbose_name="实勘状态",
help_text="draft=草稿(未提交)/submitted=已提交(已完成)",
)
gps_latitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True)
gps_longitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True)
gps_accuracy = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True)
gps_latitude = models.DecimalField(
max_digits=10,
decimal_places=7,
null=True,
blank=True,
verbose_name="GPS 纬度",
help_text="实勘打卡位置;精度 7 位小数",
)
gps_longitude = models.DecimalField(
max_digits=10,
decimal_places=7,
null=True,
blank=True,
verbose_name="GPS 经度",
help_text="实勘打卡位置;精度 7 位小数",
)
gps_accuracy = models.DecimalField(
max_digits=6,
decimal_places=2,
null=True,
blank=True,
verbose_name="GPS 精度",
help_text="米;标注定位误差",
)
description = models.TextField(blank=True, default="")
description = models.TextField(
blank=True,
default="",
verbose_name="实勘说明",
help_text="最多 200 字;经纪人现场情况描述",
)
submitted_at = models.DateTimeField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
created_by = models.ForeignKey("org.Staff", on_delete=models.RESTRICT)
submitted_at = models.DateTimeField(
null=True,
blank=True,
verbose_name="提交时间",
help_text="status 变为 submitted 时记录NULL=尚未提交",
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
updated_at = models.DateTimeField(auto_now=True, verbose_name="最后更新时间")
created_by = models.ForeignKey(
"org.Staff",
on_delete=models.RESTRICT,
verbose_name="实勘人",
help_text="禁止置 NULL 保留审计",
)
class Meta:
db_table = "field_surveys"
@@ -41,16 +82,58 @@ class FieldSurvey(UUIDPrimaryKeyModel):
class SurveyPhoto(UUIDPrimaryKeyModel):
survey = models.ForeignKey(FieldSurvey, on_delete=models.CASCADE, related_name="photos")
category = models.CharField(max_length=20, choices=PropertySurveyPhotoCategory.choices)
file_key = models.TextField()
thumbnail_key = models.TextField(blank=True, default="")
file_size = models.IntegerField(null=True, blank=True)
width = models.IntegerField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
sort_order = models.SmallIntegerField(default=0)
is_vr_screenshot = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
survey = models.ForeignKey(
FieldSurvey,
on_delete=models.CASCADE,
related_name="photos",
verbose_name="所属实勘",
help_text="实勘删除时联级删除",
)
category = models.CharField(
max_length=20,
choices=PropertySurveyPhotoCategory.choices,
verbose_name="照片空间分类",
help_text="layout=户型图/living_room=客厅/dining_room=餐厅/bedroom=卧室/bathroom=卫生间/kitchen=厨房/entrance=门厅/balcony=阳台/study=书房/indoor_other=室内其他/outdoor=外景",
)
file_key = models.TextField(
verbose_name="原图存储路径",
help_text="Cloudflare R2 对象路径",
)
thumbnail_key = models.TextField(
blank=True,
default="",
verbose_name="缩略图路径",
help_text="Cloudflare Images 自动生成",
)
file_size = models.IntegerField(
null=True,
blank=True,
verbose_name="文件大小",
help_text="bytes",
)
width = models.IntegerField(
null=True,
blank=True,
verbose_name="图片宽度",
help_text="像素;上传时解析",
)
height = models.IntegerField(
null=True,
blank=True,
verbose_name="图片高度",
help_text="像素;上传时解析",
)
sort_order = models.SmallIntegerField(
default=0,
verbose_name="排序权重",
help_text="同一空间分类内,数值越小越靠前",
)
is_vr_screenshot = models.BooleanField(
default=False,
verbose_name="是否为VR截图",
help_text="true=全景/VR截图区别于普通实拍照片",
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="上传时间")
class Meta:
db_table = "survey_photos"
@@ -68,26 +151,77 @@ class PropertyPhoto(models.Model):
Managed via RunSQL; Django ORM treats parent as unmanaged.
"""
id = models.UUIDField(primary_key=True)
created_at = models.DateTimeField()
id = models.UUIDField(primary_key=True, verbose_name="主键")
created_at = models.DateTimeField(
verbose_name="上传时间",
help_text="分区键;系统自动",
)
property = models.ForeignKey(
"fonrey_property.Property", on_delete=models.CASCADE, related_name="photos"
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="photos",
verbose_name="所属房源",
)
category = models.CharField(max_length=20, choices=PropertyPhotoCategory.choices)
file_key = models.TextField()
thumbnail_key = models.TextField(blank=True, default="")
file_name = models.CharField(max_length=255, blank=True, default="")
file_size = models.IntegerField(null=True, blank=True)
width = models.IntegerField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
category = models.CharField(
max_length=20,
choices=PropertyPhotoCategory.choices,
verbose_name="照片分类",
help_text="cover=封面/entrance=门厅/living_room=客厅/dining_room=餐厅/bedroom=卧室/bathroom=卫生间/kitchen=厨房/balcony=阳台/study=书房/indoor_other=室内其他/outdoor=外景/panorama=全景",
)
file_key = models.TextField(
verbose_name="原图存储路径",
help_text="Cloudflare R2/S3 对象路径",
)
thumbnail_key = models.TextField(
blank=True,
default="",
verbose_name="缩略图路径",
help_text="Cloudflare Images 自动生成",
)
file_name = models.CharField(
max_length=255,
blank=True,
default="",
verbose_name="原始文件名",
)
file_size = models.IntegerField(
null=True,
blank=True,
verbose_name="文件大小",
help_text="bytes",
)
width = models.IntegerField(
null=True,
blank=True,
verbose_name="图片宽度",
help_text="像素;上传时解析",
)
height = models.IntegerField(
null=True,
blank=True,
verbose_name="图片高度",
help_text="像素;上传时解析",
)
is_cover = models.BooleanField(default=False)
sort_order = models.SmallIntegerField(default=0)
is_cover = models.BooleanField(
default=False,
verbose_name="是否为封面图",
help_text="true=封面;每套房源只能有一张封面(唯一约束保证)",
)
sort_order = models.SmallIntegerField(
default=0,
verbose_name="排序权重",
help_text="同一房源内,数值越小越靠前",
)
updated_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now=True, verbose_name="最后更新时间")
created_by = models.ForeignKey(
"org.Staff", null=True, blank=True, on_delete=models.SET_NULL
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
verbose_name="上传人",
)
class Meta:
@@ -100,21 +234,46 @@ class PropertyPhoto(models.Model):
class PropertyAttachment(UUIDPrimaryKeyModel):
property = models.ForeignKey(
"fonrey_property.Property", on_delete=models.CASCADE, related_name="attachments"
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="attachments",
verbose_name="所属房源",
)
category = models.CharField(
max_length=20,
choices=PropertyAttachmentCategory.choices,
default=PropertyAttachmentCategory.OTHER,
verbose_name="附件分类",
help_text="id_card=身份证/property_cert=产权证书/commission_letter=委托书/other=其他材料",
)
file_key = models.TextField()
file_name = models.CharField(max_length=255)
file_size = models.IntegerField()
file_type = models.CharField(max_length=50, blank=True, default="")
sort_order = models.SmallIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
file_key = models.TextField(
verbose_name="附件存储路径",
help_text="Cloudflare R2 对象路径",
)
file_name = models.CharField(max_length=255, verbose_name="原始文件名")
file_size = models.IntegerField(
verbose_name="文件大小",
help_text="bytes",
)
file_type = models.CharField(
max_length=50,
blank=True,
default="",
verbose_name="MIME 类型",
help_text="如 application/pdf、image/jpeg",
)
sort_order = models.SmallIntegerField(
default=0,
verbose_name="排序权重",
help_text="控制同一房源附件的显示顺序",
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="上传时间")
created_by = models.ForeignKey(
"org.Staff", null=True, blank=True, on_delete=models.SET_NULL
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
verbose_name="上传人",
)
class Meta:
@@ -128,11 +287,33 @@ class PropertyAttachment(UUIDPrimaryKeyModel):
class PropertyTag(UUIDPrimaryKeyModel):
name = models.CharField(max_length=50)
color = models.CharField(max_length=7, blank=True, default="")
is_system = models.BooleanField(default=False)
sort_order = models.IntegerField(default=0)
is_active = models.BooleanField(default=True)
name = models.CharField(
max_length=50,
verbose_name="标签名称",
help_text="最多 50 字;如:学区/地铁口/满五唯一",
)
color = models.CharField(
max_length=7,
blank=True,
default="",
verbose_name="显示颜色",
help_text="HEX 色值,如 #FF5733前端标签徽章颜色",
)
is_system = models.BooleanField(
default=False,
verbose_name="是否系统预置",
help_text="true=系统内置标签不可删除false=运营自定义标签可删",
)
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 = "property_tags"
@@ -142,10 +323,16 @@ class PropertyTag(UUIDPrimaryKeyModel):
class PropertyTagRelation(models.Model):
property = models.ForeignKey(
"fonrey_property.Property", on_delete=models.CASCADE, related_name="tag_relations"
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="tag_relations",
verbose_name="所属房源",
)
tag = models.ForeignKey(
PropertyTag, on_delete=models.CASCADE, related_name="property_relations"
PropertyTag,
on_delete=models.CASCADE,
related_name="property_relations",
verbose_name="所属标签",
)
class Meta:
@@ -163,12 +350,19 @@ class PropertyTagRelation(models.Model):
class PropertyFavorite(models.Model):
staff = models.ForeignKey(
"org.Staff", on_delete=models.CASCADE, related_name="favorite_properties"
"org.Staff",
on_delete=models.CASCADE,
related_name="favorite_properties",
verbose_name="收藏人",
help_text="员工注销时删除收藏记录",
)
property = models.ForeignKey(
"fonrey_property.Property", on_delete=models.CASCADE, related_name="favorited_by"
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="favorited_by",
verbose_name="收藏的房源",
)
created_at = models.DateTimeField(auto_now_add=True)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="收藏时间")
class Meta:
db_table = "property_favorites"