对于在模型中使用ForeignKey
,我有一个简短的问题。
假设我有模型Car
和EngineType
。我希望Car
具有EngineType
作为外键来填充汽车引擎。那很容易。
我的问题是这样的:可以说EngineType
仅应显示正在生产的活动实例,因此,如果它们停止从1970年代开始生产3.5 liter 120 hp
引擎,我就不希望这样做在创建新车时会出现在选择的发动机类型上。另一部分是,我希望所有记录都保留在汽车数据库中以进行历史报告。所以发生了什么事,我尝试删除上述引擎,如果有的话
on_delete=CASCADE
这没做我想要的,因为我丢失了历史数据。如果有
on_delete=PROTECT
我无法删除不需要的引擎模型。
您如何处理?
答案 0 :(得分:1)
一种选择是让您的模型像这样(基本上是您已经提出的模型):
class EngineType(models.Model):
...
is_active = models.BooleanField(
default=True)
...
class Car(models.Model):
...
engine_type = models.ForeignKey(
to=EngineType,
on_delete=models.PROTECT)
...
,并且永远不要删除任何曾经使用过的EngineType
实例。旧引擎需要标记为instance.is_active = False
。
然后,您需要在表单和视图中检查是否只有活动EngineType
实例可以分配给新车。有一些问题可以解决这个问题,例如this one。
这可能看起来像这样(假设您使用ModelForm
):
class CarForm(ModelForm):
class Meta:
model = Car
fields = [
...
'engine_type',
...
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['engine_type'].queryset = EngineType.objects.filter(is_active=True)
此代码将确保通过此表格仅可将活动引擎分配给该车。
您只需要确保引擎类型不能通过其他视图或表单更改,或者也可以在其中进行相同的检查。