запутался в иностранном ключе django - PullRequest
9 голосов
/ 15 января 2012

Все,

Я упускаю что-то фундаментальное в базовой модели 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 Ответ

15 голосов
/ 16 января 2012

Если у каждого автомобиля есть один производитель, то вы должны использовать внешний ключ от Car до Manufacturer.Это позволит нескольким автомобилям иметь одного и того же производителя, и производители не будут удалены при удалении автомобилей.Поле «многие ко многим» предполагает, что один автомобиль может иметь несколько производителей.

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

Для вашего представления я сначала попытался бы написать представления для форм и наборов форм по отдельности и убедиться, что вы понимаете взаимосвязи между вашими моделями, прежде чем объединить их все в одном представлении.

Этот вопрос Переполнение стека объясняет, как одновременно использовать форму и встроенный набор форм (эквивалентно моделям Car и Wheel в вашем случае).Для производителя вы, вероятно, захотите exclude поле manufacturer из вашего CarForm, а затем установите его в своем поле зрения перед сохранением.

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