Я думаю, ви мали б тут додати нове ModelMultipleChoiceFieldдо свого PizzaFormта вручну зв’язати це поле форми з полем моделі, оскільки Django не буде робити це автоматично для вас.
Наступний фрагмент може бути корисним:
class PizzaForm(forms.ModelForm):
class Meta:
model = Pizza
toppings = forms.ModelMultipleChoiceField(queryset=Topping.objects.all())
def __init__(self, *args, **kwargs):
if kwargs.get('instance'):
initial = kwargs.setdefault('initial', {})
initial['toppings'] = [t.pk for t in kwargs['instance'].topping_set.all()]
forms.ModelForm.__init__(self, *args, **kwargs)
def save(self, commit=True):
instance = forms.ModelForm.save(self, False)
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
instance.topping_set.clear()
instance.topping_set.add(*self.cleaned_data['toppings'])
self.save_m2m = save_m2m
if commit:
instance.save()
self.save_m2m()
return instance
Це PizzaFormможе бути використано скрізь, навіть в адмінці:
from django.contrib.admin import site, ModelAdmin
from yourapp.models import Pizza
from yourapp.forms import PizzaForm
class PizzaAdmin(ModelAdmin):
form = PizzaForm
site.register(Pizza, PizzaAdmin)
Примітка
save()Метод може бути трохи занадто багатослівний, але ви можете спростити його , якщо вам не потрібно підтримувати commit=Falseситуацію, тоді буде так:
def save(self):
instance = forms.ModelForm.save(self)
instance.topping_set.clear()
instance.topping_set.add(*self.cleaned_data['toppings'])
return instance
Pizzaможе мати багатоToppings. КоженToppingможе мати багатоPizzas. Але якщо я додаю aToppingдо aPizza, чи цеPizzaавтоматично має aTopping, і навпаки?