混淆了django foreignkey,manytomanyfield,inlineformset_factories

时间:2012-01-15 18:06:38

标签: django foreign-keys many-to-many inline-formset

所有

我遗漏了Django的ForeingKeys与ManyToManyFields的基础模型的基本内容。

假设我正在构建一个关于汽车的应用程序。我可能会有以下课程:

 class Car(models.Model):
   carName = models.CharField()

 class Manufacturer(models.Model):
   manufacturerName = models.CharField()

 class Wheel(models.Model):
   radius = models.IntegerField()

到目前为止一切顺利。现在这些类之间存在一些关系。汽车有制造商,有(四)轮胎。从概念上讲,虽然存在差异。制造商通过“聚合”相关;制造商可以与多辆汽车相关联;删除Car实例不应该导致该汽车的制造商被删除。车轮通过“组合”相关;与汽车相关的每四个车轮都只与那辆汽车相关联;删除汽车,车轮也应该删除。

因此,直观地说,这意味着我应该做以下事情:

 class Car(models.Model):
   carName = models.CharField()
   manufacturer = models.ManyToManyField("Manufacturer")
   wheels = models.ForeignKey("Wheel")

最终,我想使用inlineformset_factories,以便用户可以同时填写有关汽车,其制造商和车轮的详细信息。像这样:

 class CarForm(ModelForm):
   class Meta:
     model = Car

 class ManufacturerForm(ModelForm):
   class Meta:
     model = Manufacturer

 class WheelForm(ModelForm):
   class Meta:
     model = Wheel

 Manufacturer_formset = inlineformset_factory(Car,Manufacturer,formset=ManufacturerForm)
 Wheel_formset = inlineformset_factory(Car,Wheel,formset=WheelForm)

但我发现的大部分文档都表明ForiegnKey应该从Wheel转向Car。这看起来倒退了,因为Wheel_formset会向用户显示Car(“carName”)的所有字段而不是Wheel(“radius”)。

输入这个问题的行为让我感到困惑。任何人都可以了解我如何构建一个包含所有汽车领域的表格,然后是所有制造商领域,然后是所有车轮领域。

由于

1 个答案:

答案 0 :(得分:15)

如果每辆车都有一个制造商,那么您应该使用从CarManufacturer的外键。这将允许多辆汽车拥有相同的制造商,并且当汽车被删除时不会删除制造商。许多领域都表明,一辆汽车可以拥有多家制造商。

Wheel应该有Car的外键。这将允许多个车轮拥有相同的汽车,并且当汽车被删除时默认的Django行为将是删除车轮。

所以你的模型应该是这样的:

class Manufacturer(models.Model):
    name = models.CharField()

class Car(models.Model):
    name = models.CharField()
    manufacturer = models.ForeignKey("Manufacturer")

class Wheel(models.Model):
    radius = models.IntegerField()
    car = models.ForeignKey("Car")

对于您的视图,我首先尝试单独为表单和表单集编写视图,并确保在将模型组合在一个视图中之前了解模型之间的关系。

Stack Overflow question说明了如何同时使用表单和内联表单集(相当于您案例中的CarWheel模型)。对于制造商,您可能需要manufacturer CarForm ... manufacturer = ManufacturerForm.save() car = CarForm.save(commit=False) car.manufacturer = manufacturer car.save() ... 字段,然后在保存前将其设置在视图中。

{{1}}