我想你会在这里新添加
ModelMultipleChoiceField到你
PizzaForm,并手动链接,表单字段与模型领域,如Django会不会为你做自动。
以下代码段可能会有所帮助:
class PizzaForm(forms.ModelForm): class meta: model = Pizza # Representing the many to many related field in Pizza toppings = forms.ModelMultipleChoiceField(queryset=Topping.objects.all()) # Overriding __init__ here allows us to provide initial # data for 'toppings' field def __init__(self, *args, **kwargs): # only in case we build the form from an instance # (otherwise, 'toppings' list should be empty) if kwargs.get('instance'): # We get the 'initial' keyword argument or initialize it # as a dict if it didn't exist. initial = kwargs.setdefault('initial', {}) # The widget for a ModelMultipleChoiceField expects # a list of primary key for the selected data. initial['toppings'] = [t.pk for t in kwargs['instance'].topping_set.all()] forms.ModelForm.__init__(self, *args, **kwargs) # Overriding save allows us to process the value of 'toppings' field def save(self, commit=True): # Get the unsave Pizza instance instance = forms.ModelForm.save(self, False) # Prepare a 'save_m2m' method for the form, old_save_m2m = self.save_m2m def save_m2m():old_save_m2m()# This is where we actually link the pizza with toppingsinstance.topping_set.clear()instance.topping_set.add(*self.cleaned_data['toppings']) self.save_m2m = save_m2m # Do we need to save all changes now? if commit: instance.save() self.save_m2m() return instance
这
PizzaForm然后可以使用无处不在,甚至在admin:
# yourapp/admin.pyfrom django.contrib.admin import site, ModelAdminfrom yourapp.models import Pizzafrom yourapp.forms import PizzaFormclass PizzaAdmin(ModelAdmin): form = PizzaFormsite.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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)