You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django如何将国家与州模型存入同一张数据库表并设置parent_id

实现国家与州数据同表存储的方案

一、模型重构优化

调整现有模型,适配业务需求同时遵循Django最佳实践:

from django.db import models

class CustomerLocation(models.Model):
    # 新增类型枚举,明确区分国家/州
    TYPE_CHOICES = (
        ('country', '国家'),
        ('state', '州'),
    )
    parent_id = models.IntegerField(default=0)
    name = models.CharField(max_length=100)
    status = models.CharField(max_length=100, default='nil')
    # 若关联用户建议改为ForeignKey,暂时保持原有字段类型
    added_by = models.IntegerField(default=1)
    updated_by = models.IntegerField(default=1)
    # 用Django自带自动时间字段替代自定义函数
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    type = models.CharField(max_length=20, choices=TYPE_CHOICES)

    class Meta:
        db_table = "customer_location"

    def __str__(self):
        return self.name

    # 自动处理parent_id逻辑,无需手动设置
    def save(self, *args, **kwargs):
        if self.type == 'country':
            self.parent_id = 0
        super().save(*args, **kwargs)

二、数据录入示例

创建国家数据

无需手动设置parent_id,save方法会自动将其设为0:

# 创建国家
china = CustomerLocation.objects.create(
    name="中国",
    type='country'
)

创建州数据

将parent_id设为对应国家的自增ID即可:

# 创建隶属于中国的州
beijing = CustomerLocation.objects.create(
    name="北京",
    type='state',
    parent_id=china.id
)

三、关键调整说明

  • 字段类型修正:将parent_id从CharField改为IntegerField,匹配ID的数字存储特性,避免字符串转换错误。
  • 时间字段优化:用auto_now_add和auto_now自动维护创建/更新时间,替代自定义字符串转换函数,更可靠且便于时间查询。
  • 类型标识字段:新增type字段明确区分国家和州,后续可快速筛选数据(如CustomerLocation.objects.filter(type='country')获取所有国家)。
  • 自动维护parent_id:通过重写save方法,当类型为国家时自动设置parent_id=0,减少手动操作成本。

四、扩展查询示例

  • 获取某个国家下的所有州:
# 获取中国下属的所有州
china_states = CustomerLocation.objects.filter(parent_id=china.id)
  • 获取所有国家:
all_countries = CustomerLocation.objects.filter(type='country')

内容的提问来源于stack exchange,提问作者n0cuous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:05:23