2012-01-15 34 views
9

All,bối rối về django ForeignKey, manytomanyfield, inlineformset_factories

tôi thiếu cái gì cơ bản về mô hình cơ bản cho ForeingKeys của Django vs ManyToManyFields.

Giả sử tôi đang xây dựng một ứng dụng về ô tô. Tôi có thể có các lớp sau:

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

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

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

Cho đến nay rất tốt. Bây giờ có một số mối quan hệ giữa các lớp này. Một chiếc xe có một nhà sản xuất và có (bốn) lốp xe. Về mặt khái niệm, có một sự khác biệt. Các nhà sản xuất có liên quan thông qua "tập hợp"; một nhà sản xuất có thể được kết hợp với nhiều xe ô tô; việc xóa một phiên bản Xe hơi cũng không được làm cho nhà sản xuất ô tô đó bị xóa. Các bánh xe có liên quan thông qua "thành phần"; mỗi bốn bánh xe liên kết với một chiếc xe được kết hợp với điều đó và chỉ có chiếc xe đó; xóa xe và bánh xe cũng sẽ bị xóa.

Vì vậy, bằng trực giác, đó có nghĩa là tôi phải làm như sau:

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

Cuối cùng, tôi muốn sử dụng inlineformset_factories để người dùng có thể điền vào thông tin chi tiết về một chiếc xe, nhà sản xuất của nó và bánh xe tất cả ở cùng một lúc. Một cái gì đó như thế này:

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) 

Nhưng hầu hết tài liệu tôi tìm thấy cho thấy ForiegnKey nên đi từ Wheel to Car. Điều này có vẻ ngược lại với tôi, kể từ khi Wheel_formset sau đó sẽ trình bày cho người dùng tất cả các trường cho một ô tô ("carName") và không phải là một bánh xe ("bán kính").

Chỉ hành động nhập câu hỏi này làm tôi bối rối. Ai đó có thể làm sáng tỏ một số cách tôi có thể xây dựng một hình thức có tất cả các lĩnh vực ô tô, và sau đó là tất cả các lĩnh vực của nhà sản xuất, và sau đó là tất cả các trường bánh xe.

Cảm ơn

Trả lời

15

Nếu mỗi xe có một nhà sản xuất, sau đó bạn nên sử dụng một khóa ngoại từ Car để Manufacturer. Điều này sẽ cho phép nhiều xe ô tô có cùng một nhà sản xuất và nhà sản xuất sẽ không bị xóa khi xe ô tô bị xóa. Nhiều trường cho thấy một chiếc xe có thể có nhiều nhà sản xuất.

Wheel phải có khóa ngoài là Car. Điều này sẽ cho phép nhiều bánh xe để có cùng một chiếc xe, và hành vi Django mặc định khi một chiếc xe bị xóa sẽ được để xóa các bánh xe.

Vì vậy, mô hình của bạn sẽ giống như thế này:

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") 

Đối với quan điểm của bạn, đầu tiên tôi sẽ cố gắng viết quan điểm cho các hình thức và formsets riêng, và chắc chắn rằng bạn hiểu được mối quan hệ giữa các mô hình của bạn trước khi bạn đưa tất cả chúng lại với nhau trong một chế độ xem.

Stack Overflow question này giải thích cách sử dụng biểu mẫu và biểu mẫu nội tuyến cùng một lúc cùng một lúc (tương đương với các mô hình CarWheel trong trường hợp của bạn). Đối với nhà sản xuất, bạn có thể muốn exclude trường manufacturer từ CarForm của bạn, sau đó đặt nó trong chế độ xem của bạn trước khi bạn lưu.

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

Cảm ơn bạn đã phản hồi này.Tôi có thể xác nhận rằng nếu một chiếc xe có thể có nhiều hơn một nhà sản xuất (nói rằng, nó được xây dựng bởi một đội), sau đó tôi nên sử dụng một ManyToManyField? – trubliphone

+0

Có, nếu xe hơi có thể có nhiều hơn một nhà sản xuất (và một nhà sản xuất có thể chế tạo thêm một chiếc xe đó), thì hãy sử dụng 'ManyToManyField'. – Alasdair

+3

Bit muộn đến bữa tiệc nhưng sẽ không phải là một chìa khóa nước ngoài là một mối quan hệ nhiều đến một? –

Các vấn đề liên quan