Django模型继承:创建基础Car模型关联子车型并实现统一查询
Django 模型继承统一关联实现方案
适用场景
需要基于同一基础父模型衍生多类子模型,统一绑定和其他模型的关联关系,无需为每个子模型单独配置关联,可直接通过父模型查询所有子类的关联数据。
代码实现
1. 定义基础父模型
父模型不要设置abstract = True,直接在父模型中配置和User的关联字段,所有子模型会自动继承该关联:
from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class Car(models.Model): # 所有车型通用字段 name = models.CharField(max_length=100, verbose_name="车型名称") production_year = models.IntegerField(verbose_name="生产年份") price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="售价") # 统一绑定和User的关联 owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="cars", verbose_name="所属用户") class Meta: verbose_name = "车辆基础信息" verbose_name_plural = verbose_name
2. 定义子车型模型
直接继承Car类,仅需配置子车型独有的字段即可,无需重复配置关联:
class Truck(Car): # 卡车独有字段 max_load = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="最大载重(吨)") container_size = models.CharField(max_length=50, verbose_name="货箱尺寸") class SportCar(Car): # 跑车独有字段 max_speed = models.IntegerField(verbose_name="最高时速(km/h)") acceleration = models.DecimalField(max_digits=3, decimal_places=1, verbose_name="百公里加速时间(s)")
数据查询方法
查询指定用户的所有车辆
直接通过父模型Car或者User的关联属性即可查询,返回结果包含所有子车型的基础数据:
# 方式1:通过User实例的关联属性查询 user = User.objects.get(id=xxx) user_all_cars = user.cars.all() # 方式2:直接过滤Car表 user_all_cars = Car.objects.filter(owner_id=xxx)
获取子车型独有字段
多表继承会自动为父模型实例生成小写子模型名的属性,用来访问子模型的独有数据:
for car in user_all_cars: # 判断车型类型,获取对应子类实例 if hasattr(car, 'truck'): print(f"卡车:{car.name},最大载重:{car.truck.max_load}吨") elif hasattr(car, 'sportcar'): print(f"跑车:{car.name},最高时速:{car.sportcar.max_speed}km/h")
注意事项
- 不要将
Car设置为抽象基类(即不要加abstract = True配置),抽象基类不会生成独立数据表,无法承载统一的关联关系。 - 如果子车型数量较多,建议在
Car类中新增car_type字段,用choices枚举所有车型类型,创建实例时自动赋值,判断类型时直接读取该字段即可,比反复调用hasattr效率更高。 - 如果需要对子模型做单独的复杂查询,可直接操作对应子模型的表,关联关系会自动同步到父表。
内容的提问来源于stack exchange,提问作者Айбулат Нотфуллин
相关产品推荐
相关产品推荐

