Ich denke , man würde hier eine neue hinzufügen , ModelMultipleChoiceField
um Ihre PizzaForm
und verknüpfen manuell dieses Formularfeld mit dem Modellfeld, wie Django wird das nicht automatisch für Sie.
Das folgende Snippet könnte hilfreich sein:
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
Dies PizzaForm
kann dann überall verwendet werden, auch im Admin:
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)
Hinweis
Die save()
Methode ist vielleicht etwas zu ausführlich, aber Sie können sie vereinfachen, wenn Sie die commit=False
Situation nicht unterstützen müssen. Dann sieht es so aus :
def save(self):
instance = forms.ModelForm.save(self)
instance.topping_set.clear()
instance.topping_set.add(*self.cleaned_data['toppings'])
return instance
Pizza
kann vieleTopping
s haben. JederTopping
kann vielePizza
s haben. Aber wenn ich aTopping
zu a hinzufügePizza
, hat dasPizza
dann automatisch ein aTopping
und umgekehrt?