Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 在尝试保留历史数据时,请正确设置\u delete上的外键_Django_Django Models_Foreign Keys - Fatal编程技术网

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)