2012-01-15 69 views
9

所有,困惑Django的外键,manytomanyfield,inlineformset_factories

我失去了一些东西有关Django的ForeingKeys VS 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_formset会向用户显示Car(“carName”)而不是Wheel(“radius”)的所有字段。

只是打字这个问题的行为让我感到困惑。任何人都可以阐明我如何构建一个拥有所有汽车领域,然后是所有制造商领域,然后是所有车轮领域的形式。

感谢

回答

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车型在你的情况)一起使用的一种形式和内联表单集。对于制造商而言,您可能需要从CarFormexcludemanufacturer字段,然后在保存之前将其设置在您的视图中。

... 
manufacturer = ManufacturerForm.save() 
car = CarForm.save(commit=False) 
car.manufacturer = manufacturer 
car.save() 
... 
+0

谢谢你的回应。我可以证实,如果一辆汽车可以有多个制造商(比如它是由一个团队制造的),那么我应该使用一个ManyToManyField? – trubliphone 2012-01-16 04:38:42

+0

是的,如果汽车可以有多个制造商(并且制造商可以制造更多的汽车),则使用'ManyToManyField'。 – Alasdair 2012-01-16 10:22:54

+3

派对迟到了,但是外键不会是多对一的关系吗? – 2014-11-04 14:36:26