具有反向ManytoMany字段的ModelForm(ModelForm with a reverse ManytoMany field)

我无法让ModelMultipleChoiceField显示模型实例的初始值。 我一直无法找到有关该领域的任何文档,我一直在阅读的例子太令人困惑了。 Django:ModelMultipleChoiceField没有选择初始选择似乎是相似的,但是那里给出的解决方案对模型实例来说不是动态的。

这是我的情况(每个数据库用户连接到一个或多个项目):

models.py

from django.contrib.auth.models import User class Project(Model): users = ManyToManyField(User, related_name='projects', blank=True)

forms.py

from django.contrib.admin.widgets import FilteredSelectMultiple class AssignProjectForm(ModelForm): class Meta: model = User fields = ('projects',) projects = ModelMultipleChoiceField( queryset=Project.objects.all(), required=False, widget=FilteredSelectMultiple('projects', False), )

views.py

def assign(request): if request.method == 'POST': form = AssignProjectForm(request.POST, instance=request.user) if form.is_valid(): form.save() return HttpResponseRedirect('/index/') else: form = AssignProjectForm(instance=request.user) return render_to_response('assign.html', {'form': form})

它返回的表单不是选择实例的链接项目(它看起来像: Django多选小部件? )。 此外,它不会使用保存表单时所做的任何选择来更新用户。

编辑:使用此方法管理解决此问题: http : //code-blasphemies.blogspot.com/2009/04/dynamically-created-modelmultiplechoice.html

I'm having trouble getting ModelMultipleChoiceField to display the initial values of a model instance. I haven't been able to find any documentation about the field, and the examples I've been reading are too confusing. Django: ModelMultipleChoiceField doesn't select initial choices seems to be similar, but the solution that was given there is not dynamic to the model instance.

Here is my case (each database user is connected to one or more projects):

models.py

from django.contrib.auth.models import User class Project(Model): users = ManyToManyField(User, related_name='projects', blank=True)

forms.py

from django.contrib.admin.widgets import FilteredSelectMultiple class AssignProjectForm(ModelForm): class Meta: model = User fields = ('projects',) projects = ModelMultipleChoiceField( queryset=Project.objects.all(), required=False, widget=FilteredSelectMultiple('projects', False), )

views.py

def assign(request): if request.method == 'POST': form = AssignProjectForm(request.POST, instance=request.user) if form.is_valid(): form.save() return HttpResponseRedirect('/index/') else: form = AssignProjectForm(instance=request.user) return render_to_response('assign.html', {'form': form})

The form that it returns is not selecting the instance's linked projects (it looks like: Django multi-select widget?). In addition, it doesn't update the user with any selections made when the form is saved.

Edit: Managed to solve this using the approach here: http://code-blasphemies.blogspot.com/2009/04/dynamically-created-modelmultiplechoice.html

最满意答案

ModelForm不会自动用于反向关系。

save()没有发生任何事情,因为ModelForm只知道如何处理自己的字段 - projects不是User模型上的字段,它只是表单上的字段。

您必须告诉您的表单如何使用您的新领域进行自我保存。

def save(self, *args, **kwargs): for project in self.cleaned_data.get('projects'): project.users.add(self.instance) return super(AssignProjectForm, self).save(*args, **kwargs)

ModelForm's don't automatically work for reverse relationships.

Nothing is happening on save() because a ModelForm only knows what to do with its own fields - projects is not a field on the User model, it's just a field on your form.

You'll have to tell your form how to save itself with this new field of yours.

def save(self, *args, **kwargs): for project in self.cleaned_data.get('projects'): project.users.add(self.instance) return super(AssignProjectForm, self).save(*args, **kwargs)

更多推荐