Django 在尝试保留历史数据时,请正确设置\u delete上的外键
我有一个关于在模型中使用Django 在尝试保留历史数据时,请正确设置\u delete上的外键,django,django-models,foreign-keys,Django,Django Models,Foreign Keys,我有一个关于在模型中使用ForeignKey的快速问题 假设我有车型汽车和引擎类型。我希望汽车具有引擎类型作为外键来填充汽车引擎。这很容易 我的问题是:假设EngineType只应显示正在生产的活动实例,因此,如果他们从1970年代开始停止生产3.5升120 hp发动机,我不希望它出现在您创建新车时的发动机类型选择中。另一方面,我希望所有记录都保存在汽车数据库中,以便进行历史报告。因此,我会尝试删除上面提到的引擎,如果我有 on_delete=CASCADE 这不符合我的要求,因为我丢失了历史
ForeignKey
的快速问题
假设我有车型汽车
和引擎类型
。我希望汽车
具有引擎类型
作为外键来填充汽车引擎。这很容易
我的问题是:假设EngineType
只应显示正在生产的活动实例,因此,如果他们从1970年代开始停止生产3.5升120 hp
发动机,我不希望它出现在您创建新车时的发动机类型选择中。另一方面,我希望所有记录都保存在汽车数据库中,以便进行历史报告。因此,我会尝试删除上面提到的引擎,如果我有
on_delete=CASCADE
这不符合我的要求,因为我丢失了历史数据。如果我有
on_delete=PROTECT
我无法删除不需要的发动机型号
您如何处理此问题?一个选择是让您的模型像这样(基本上是您已经提出的): 并且永远不要删除任何曾经使用过的
EngineType
实例。旧引擎需要标记为instance.is_active=False
然后,在表单和视图中,您需要检查是否只能将活动的EngineType
实例分配给新车。例如,有一些问题可以解决这个问题
可能是这样的(如果您使用ModelForm
):
此代码将确保通过此表单只能将激活的发动机分配给此汽车
您只需确保发动机类型不能通过其他视图或表单更改,或在这些视图或表单中建立相同的检查。因此,您不希望删除过时的
EngineType
车型,而只是在创建新汽车时不在表单中显示它们,对吗?您是否考虑过制作只显示当前正在生产的EngineType
s的自定义表单?您可以将生产中的字段添加到EngineType
,然后使用该字段进行排序。
class EngineType(models.Model):
...
is_active = models.BooleanField(
default=True)
...
class Car(models.Model):
...
engine_type = models.ForeignKey(
to=EngineType,
on_delete=models.PROTECT)
...
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)