Я думаю, ви мали б тут додати нове 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
може мати багатоTopping
s. КоженTopping
може мати багатоPizza
s. Але якщо я додаю aTopping
до aPizza
, чи цеPizza
автоматично має aTopping
, і навпаки?