Я предполагаю, что вам придется здесь добавить новое 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
, и наоборот?