Django中如何继承模型字段并创建独立数据表?
解决方案
核心问题分析
你之前用Django多表继承(直接继承具象CompanyRanking模型)的方式行不通,因为多表继承会自动在父子模型间生成一对一关联:子模型仅存储新增的batch字段,其余字段依赖父表,既没法修改父模型字段的related_name,也无法独立更新这些字段。下面提供两种可行方案:
方法1:抽象基类重构(推荐)
把通用字段抽离到抽象基类,让两个模型各自继承并定义独立的关联属性与related_name,最终两个模型对应完全独立的数据库表,字段可单独更新。
- 定义抽象基类,封装共享字段:
from django.db import models class BaseCompanyRanking(models.Model): """基础公司排名抽象模型,存放通用字段""" company = models.ForeignKey( 'companies.company', on_delete=models.CASCADE, null=True ) user = models.ForeignKey( 'users.user', on_delete=models.CASCADE, null=True ) extra_data = models.JSONField( null=True, blank=True ) class Meta: abstract = True
- 重构原
CompanyRanking模型,继承基类并设置专属related_name:
class CompanyRanking(BaseCompanyRanking): """基于分钟使用量的公司排名模型""" company = models.ForeignKey( 'companies.company', on_delete=models.CASCADE, null=True, related_name='ranking' ) user = models.ForeignKey( 'users.user', on_delete=models.CASCADE, null=True, related_name='ranking_position' )
- 创建
CompanyRankingByBatch模型,继承基类并添加批次关联,同时设置独立的related_name:
class CompanyRankingByBatch(BaseCompanyRanking): """基于日期批次的公司排名模型""" company = models.ForeignKey( 'companies.company', on_delete=models.CASCADE, null=True, related_name='ranking_by_batch' ) user = models.ForeignKey( 'users.user', on_delete=models.CASCADE, null=True, related_name='ranking_position_by_batch' # 自定义关联名称 ) batch = models.ForeignKey( 'companies.CompanyBatchByDate', on_delete=models.SET_NULL, null=True, related_name='ranking_by_batch' )
方法2:手动复制字段(适合无法重构原模型的场景)
如果不能修改已有的CompanyRanking模型,直接复制其所有字段到新模型,添加批次字段并设置独立的related_name:
class CompanyRankingByBatch(models.Model): """基于日期批次的公司排名模型""" company = models.ForeignKey( 'companies.company', on_delete=models.CASCADE, null=True, related_name='ranking_by_batch' ) user = models.ForeignKey( 'users.user', on_delete=models.CASCADE, null=True, related_name='ranking_position_by_batch' # 独立关联名称 ) extra_data = models.JSONField( null=True, blank=True ) batch = models.ForeignKey( 'companies.CompanyBatchByDate', on_delete=models.SET_NULL, null=True, related_name='ranking_by_batch' )
内容的提问来源于stack exchange,提问作者Pablo Calderon
相关产品推荐
相关产品推荐

