2011-08-10 25 views
4

我无法使ModelMultipleChoiceField显示模型实例的初始值。我一直无法找到关于该领域的任何文档,而我一直在阅读的例子太混乱。 Django: ModelMultipleChoiceField doesn't select initial choices似乎是相似的,但在那里给出的解决方案对模型实例不具有动态性。带有反转ManytoMany字段的ModelForm

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

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}) 

形式th在它返回时不选择实例的链接项目(它看起来像:Django multi-select widget?)。另外,它不会在保存表单时进行任何选择来更新用户。

编辑:管理这这里使用的方法来解决:http://code-blasphemies.blogspot.com/2009/04/dynamically-created-modelmultiplechoice.html

回答

4

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) 
+3

这就是为什么它不能正确初始化与反向关系的值?有没有办法让它正确初始化? – Edd

+0

另外,有没有办法设置self.instance.users.projects = self.cleaned_data.get('projects')?这种方式只会添加,如果删除它们将不会删除对象。 – Edd

+0

我想当前的解决方案可以添加,但不能删除条目。这里是支持删除条目的版本:http://stackoverflow.com/a/21480139/633961 – guettli