2015-06-20 87 views
2

我对我的第一个Django项目工作的ModelForm预填充复选框。Django的:使用自定义查询

我有两个模型之间的许多一对多的关系:用户和项目。 虽然更新项目,我想表明与添加新成员,删除现有成员字段根据当前工程用户正确选择形式。

这里是我试过到目前为止:

  1. 从URL
  2. 获取当前项目通过当前项目,以标准格式
  3. 形式,自定义查询集运行。

问题:不显示查询集的结果。

在views.py

类UpdateProject(LogInRequiredMixin,更新视图):

""" Class to Edit Project. 
""" 

form_class = ProjectUpdateForm 
template_name = 'project/create.html' 

def get_object(self): 
    self.project_instance = models.Project.objects.get(pk=self.kwargs['project']) 
     return self.project_instance 

def get_form_kwargs(self): 
    kwargs = super(UpdateProject, self).get_form_kwargs() 
    kwargs.update({'project': self.project_instance}) 
    return kwargs 

对于形式 ProjectUpDateForm

class ProjectUpdateForm(forms.ModelForm): 
    """ Form to update Project Field. """ 

    add_member = forms.CharField(label="Add New Members", widget=forms.CheckboxSelectMultiple) 
    del_member = forms.CharField(label="Remove Members", widget=forms.CheckboxSelectMultiple) 

    def __init__(self, *args, **kwargs): 
     self.project = kwargs.pop('project') 
     super(ProjectUpdateForm, self).__init__(*args, **kwargs) 
     print MyUser.objects.exclude(pk__in=self.project.members.all()) 
     print MyUser.objects.filter(pk__in=self.project.members.all()) 

     self.fields['add_member'].queryset = MyUser.objects.exclude(pk__in=self.project.members.all()) 
     self.fields['del_member'].queryset = MyUser.objects.filter(pk__in=self.project.members.all()) 

    # Rest of Class Logic 

打印对帐单的工作,并返回正确的结果,但我无法在应用中查看结果。它显示空白。

此外,我想知道他们更容易达到相同的方式吗? (在我看来,我不应该明确地传递项目?)

+0

这两种形式的Meta类是什么? – Pcriulan

+0

@Pcriulan 表单 类元: 模型=项目 栏= [“标题”,“描述”] 对于View,我没有使用元 –

+0

好了,所以你需要添加你的自定义字段中的字段: fields = ['title','description','add_member','del_member']。这样你就可以告诉django了解这些领域。 – Pcriulan

回答

1

至于我能找到的,这解决了

多到许多领域明确雏型当添加的问题,你期望多重响应,所使用的模块应该是ModelMultipleChoiceField

另外,由于我们超越了init方法,并且有一个查询集,所以定义它的最好的地方是在init中。

最终形式代码:

class ProjectUpdateForm(forms.ModelForm): 
    """ Form to update Project Field. """ 


    def __init__(self, *args, **kwargs): 
     self.project = kwargs.pop('project') 
     super(ProjectUpdateForm, self).__init__(*args, **kwargs) 

     self.fields['add_member'] = forms.ModelMultipleChoiceField(label="Add New members", 
                    widget=forms.CheckboxSelectMultiple, 
                    queryset=MyUser.objects.exclude(pk__in=self.project.members.all())) 
     self.fields['del_member'] = forms.ModelMultipleChoiceField(label="Remove Members", 
                    widget=forms.CheckboxSelectMultiple, 
                    queryset=MyUser.objects.filter(pk__in=self.project.members.all())) 

    class Meta: 
     model = Project 
     fields = ['title', 'description'] 

    #Rest of Form Logic 

这应该这样做!我们并不需要完全初始化过来写(如果查询需要通过


可能是有人

万一,我们已经在我们的模型中定义的字段有用参数)

我们可以通过 self.fields [“FIELD_NAME”]定义它查询集在初始化。查询集=逻辑

而在元ç添加插件姑娘。


PS:我仍然在寻找更简单的方法来访问当前对象,而不是通过查看被显式传递,但!

0

我了解添加add_memberdel_member操作的想法。

但是,为什么你不能仅仅使用一个ModelMultipleChoiceField来显示可能在项目中的每个用户,只是复选框显示已经参与项目的用户?

我没有测试这一点,但它可能看起来像:

class ProjectForm(forms.ModelForm): 

    class Meta: 
     model = Project 
     fields = ['title', 'description'] 

    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     current_members = self.instance.members.all() # What are the current members? 
     possible_members = User.objects.all() # Change this if you want a different set of users to add. 
     self.fields['members'] = forms.ModelMultipleChoiceField(label="Members", 
                   widget=forms.CheckboxSelectMultiple, 
                   queryset=possible_members, 
                   initial=current_members, 
                   required=False) # If it can be empty 

    def save(self, commit=True): 
     instance = super().save(commit=False) # Saving with commit=False add a save_m2m method to self 
     if commit: 
      instance.members.clear()   # We delete every member 
      for m in self.cleaned_data.get('members'): # We them add again every checked user as member at form submission 
       instance.members.add(m) 
      instance.save()     # We save the instance 
      self.save_m2m()     # We also save the changes in the M2M relationship. 
      return instance 

诀窍是检索用户是目前该项目实例的成员和预检复选框,以显示他们在所有用户的整个列表(勾选:用户谁是会员,未勾选:不是会员的用户)。

因此,如果您选中一个框,则添加该用户,如果取消选中该框,则会将其从成员列表中删除。